C++ 类的引入,名字空间的意义

有一天,公司来了新人,我要对他的一些属性做些基本的记录。比如,我得知道他的姓名,年龄等。那么通过编程来记录他的这些属性,很明显,我得有一个保存姓名的数组,保存年龄的数组,但是随着记录越来越完善,那么我就得不断的添加数组,如果人不多还好,但是一旦人多了起来之后,每来一个人,都要重开一边数组记录他的基本信息,首先这样代码会变得又烂又长,而且,不便于开发者管理及开发程序。所以,为了解决这种具有同一属性的数据,我们将它们的同一属性封装成一种类型,这种类型在C语言中称为结构体。

当有了这种类型之后,我可以对这些类型进行操作,比如,输出某某的姓名,年龄等等。在C中,我只要调用printf函数,再通过结构题变量的访问方式就可以轻松输出我所想要的信息,那么既然我需要得到他的信息,为何不将这种输出函数一起封装在结构体中呢?不仅仅是输出函数,或者是别的一些对数据进行操作的函数也可以封装在结构体中。

于是,新诞生的C++语言就在C语言的基础上,对结构体进行了强化,就有了类这种数据类型。类这种数据类型是一种既有成员变量又有成员函数的新类型。(哦对了,顺便带一句,C++是一种面向对象的编程语言,而面向对象的三大特征就是:封装、继承、多态)。比如有一下代码:

#include <stdlib.h>
#include <stdio.h>

class People{

	public:
		char* name;
		int age;
		char* job;
	public:
		void PrintInfo ( void ){

			printf ( "%10s%4d%10s\n", name, age, job );
		}
};

int main ( ){

	People person;
	person.name = "chentong";
	person.age = 20;
	person.job = "student";
	person.PrintInfo();

	return 0;
}

这段代码就是典型的使用类来定义的“人”的类型。

我们都知道,当去一家公司工作的时候,不可能让一个人完成所有代码,每个人都有各自的任务,然后将每个人写的代码放在一起成功运行,才是完成了一个项目。那么比如说,有两名员工A和B,A的任务是写一个关于“人”这个属性的代码,B的任务是写一个关于“狗”这个属性的代码。

那么,这个时候,A就需要将他的代码分为两个文件,一个.cpp,一个.h文件来实现。

如,A的代码:

头文件中的代码:

class People {

private:
	char* name;
	char age;
	char* job;

public:
	void SetName(char* name);
	int SetAge(char age);
	void SetJob(char* job);
	void PrintInfo(void);
};

CPP文件中的代码:

#include <stdio.h>
#include <stdlib.h>
#include "person.h"
#include <iostream>

using namespace std;

void People:: SetName(char* name) {

	this->name = name;
}

int People::SetAge(char age) {

	if (age < 0 || age > 150) {

		this->age = 0;
		return -1;
	}

	this->age = age;
	return 0;
}

void People::SetJob(char* job) {

	this->job = job;
}

void People::PrintInfo(void) {

	printf("%10s%4d%10s\n", this->name, this->age, this->job);
}

B的代码:

头文件中的代码:

class Dog {

private:
	char* name;
	char age;
public:
	void SetName(char* name);
	int SetAge(char age);
	void DisplayInfo(void);
};

CPP文件中的代码:

#include <stdlib.h>
#include <stdio.h>
#include "dog.h"
#include <iostream>

using namespace std;

void Dog::SetName(char* name) {

	this->name = name;
}

int Dog::SetAge(char age) {

	if (age < 0 || age > 150) {

		this->age = 0;
		return -1;
	}

	this->age = age;
	return 0;
}

void Dog::DisplayInfo(void) {

	printf("%10s%4d\n", this->name, this->age);
}

这样以来就分别完成了各自的任务。现在,有第三个员工C,他的任务是在主函数中实现他们两人的代码功能。于是,C的工作代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "person.h"
#include "dog.h"

using namespace std;

int main(int argc, char** argv) {

	People person;
	Dog dog;
	person.SetName("chentong");
	person.SetAge(20);
	person.SetJob("student");
	person.PrintInfo();

	dog.SetName("hashiqi");
	dog.SetAge(4);
	dog.DisplayInfo();

	system("pause");
	return 0;
}

到这里为止,只要三名员工就能完成这个项目。那么,如果这个项目非常复杂,需要1000个人合作完成,大家你写你的,我写我的,可能就会出现,定义了相同的变量名或者是定义了相同的函数名的情况。这样一来,在主函数中使用这些函数时,编译器就无法分清,调用的到底是谁写的函数,毕竟,函数名相同。所以,C++为了解决这样的一个问题,就引入了名字空间这样一个概念,把自己的工作任务需要写的代码,放在自己定义的名字空间中,这样,在主函数中使用时,只要指明是哪个名字空间中的就可以了。比如,A的工作代码,放在了名为P的名字空间中,

namespace P {

	void People::SetName(char* name) {

		this->name = name;
	}

	int People::SetAge(char age) {

		if (age < 0 || age > 150) {

			this->age = 0;
			return -1;
		}

		this->age = age;
		return 0;
	}

	void People::PrintInfo(void) {

		printf("%10s%4d\n", this->name, this->age);
	}

	void PrintVersion(void) {

		printf("chentong is a person\n");
	}

}
namespace P {

	class People {

	private:
		char* name;
		char age;
	public:
		void SetName(char* name);
		int SetAge(char age);
		void PrintInfo(void);
	};

	void PrintVersion(void);
}

这样一来,在主函数中使用时,只要指明是哪个名字空间中的,就不会出现,函数名同名,使用时报错的现象了。(名字空间

当多个人同时进行大型项目的程序开发时,可能会出现大家定义的函数名相同的情况,那么,为了解决命名冲突的问题。如果把相同名字的函数放在不同的名字空间内,不会报错,因为互不影响。

解决了如何避免多人同时工作,定义的函数名同名的问题。

接下来,又面临了一个新的问题。如何在主函数中,不出任何问题的使用这些定义在各自空间中的类。首先讲第一种,直接在想要使用的类前加上该类的名字空间,比如:

P::People person;
D::Dog dog;

这样以来,就说明了,我使用的是名字空间P中的People类;名字空间D中的Dog类。

当然,也可以不这么用,如果你想,像普通类一样使用,那么你可以在global namespace中定义,

using P::People; //把People放入global namespace,以后可以直接使用People来代替P::People
using D::Dog;   //把Dog放入global namespace,以后可以直接使用Dog来代替D::Dog

这是第二种使用方式。

当然还有第三种,就是,直接在global namespace中定义

using namesapce P;
using namespace D;

基本上,到这里为止就差不多把C++中的名字空间给讲清楚了。当然,还有类的使用。

时间: 2024-10-03 18:36:08

C++ 类的引入,名字空间的意义的相关文章

C++名字空间/C++命名空间

0.序言 名字空间是C++提供的一种解决符号名字冲突的方法. 一个命令空间是一个作用域,在不同名字空间中命名相同的符号代表不同的实体. 通常,利用定义名字空间的办法,可以使模块划分更加方便,减少模块间的相互影响. 1.名字空间的成员 定义在名字空间中的实体称为名字空间的成员. 名字空间内的名字可以被该名字空间内的其他成员直接访问,名字空间外的代码必须指定该名字位于哪个名字空间. 一个名字空间可以包含多种类型的标识符,如下面所列: 变量.常量.函数.结构体/联合体/枚举.类.嵌套名字空间 名字空间

C++名字空间详解

代码编译运行环境:VS2012+Win32+Debug 1.名字空间的由来 名字空间(namespace)是由标准C++引入的,是一种新的作用域级别.原来C++标识符的作用域分为三级:代码块({-}和函数体).类域和全局作用域.如今,在类作用域和全局作用域之间,C++标准又添加了名字空间域这一个作用域级别. 命名空间是ANSIC++引入的可以由用户命名的作用域,用来处理程序中常见的同名冲突. 2.名字空间的作用 名字空间的作用主要是为了解决日益严重的名称冲突问题.随着可重用代码的增多,各种不同的

读书笔记 effective c++ Item 43 了解如何访问模板化基类中的名字

1. 问题的引入——派生类不会发现模板基类中的名字 假设我们需要写一个应用,使用它可以为不同的公司发送消息.消息可以以加密或者明文(未加密)的方式被发送.如果在编译阶段我们有足够的信息来确定哪个信息会被发送到哪个公司,我们可以使用基于模板的解决方案: 1 class CompanyA { 2 public: 3 ... 4 void sendCleartext(const std::string& msg); 5 void sendEncrypted(const std::string&

未命名名字空间

未命名的名字空间 我们或许希望所定义的对象.函数.类类型或其他实体,它只在程序的一小段代码中可见,因为这样可以更进一步地缓解名字空间污染问题,因为我们知道该实体只 被用在很有限的地方,所以可能不想再花费太多努力来保证这个实体有惟一的名字而不会与程序其他地方声明的名字冲突.当我们在一个函数或嵌套块中声明一个对 象时,由该声明引入的名字只在声明它的块中可见,但是,如果程序员想让一个实体被多个函数使用,而又不想让该名字在整个程序中可用 又该怎么办呢? 例如 假设我们想实现一组排序函数,对 double

类作用域中名字查找的思考(《C++ primer》第四版P382)

1.问题的引入 1).观察以下第一块代码: #include <iostream> using namespace std; class Screen{ public: void test(){ dummy_fcn( ); } void dummy_fcn( ){ } }: 此代码编译无错误............... 2).再看以下第二块代码: #include <iostream> using namespace std; void test(){ dummy_fcn( );

名字空间和异常

那年是787年!公元?--Monty Python 任何规则都不可能如此一般,以至不能容许任何例外(异常).--Bobert Burton 1.模块化和界面 任何实际程序都是由一些部分组成的.例如,最简单的" Hello, world! "程序也涉及到至少两部分:用户代码要求将Hello, world!打印出来,I/O系统完成打印工作. 当一个模块使用另一个模块时,它并不需要知道有关被用模块的所有东西.理想的情况是,一个模块的大部分细节都不为其使用都所知.为此,我们就需要将一个模块和它

iOS: 学习笔记, Swift名字空间

在Swift中, 名字空间是用class(extension)嵌套来实现的, 以下用一个简单样例来进行展示 // // main.swift // SwiftNameSpace // // Created by yao_yu on 14-8-1. // Copyright (c) 2014年 yao_yu. All rights reserved. // // Swift名字空间使用实例 // import Foundation //定义顶层名字空间 class YY{ } //在YY名字空间中

C++笔记--名字空间和异常

名字空间 成员函数可以在名字空间的定义里去声明,然后再去采用一种定义方式例如:namespace__name::member_name的方式去定义这个成员函数 1 namespace parser{ 2 double prim(bool); 3 double term(bool); 4 } 5 6 double parser::prim(bool get){/*定义*/} 7 double parser::term(bool get){/*定义,这些定义式定义在命名空间之外的*/} 名字空间中的

java 8中撤销永久代,引入元空间

撤销永久代,引入元空间: 在 JDK 1.8 中,HotSpot 已经没有 "PermGen space"这个空间了,取而代之是一个叫做 Metaspace(元空间) 的东西. Java7中已经将字符串常量池从永久代移除,在Java 堆(Heap)中开辟了一块区域存放字符串常量池.而在Java8中,已经彻底没有了永久代,将方法区直接放在一个与堆不相连的本地内存区域,这个区域被叫做元空间. 移除永久代后,不会遇到永久代存在的内存溢出错误,也不会出现泄漏的数据移到交换区这样的事情.最终用户