xxx.h
namespace space{
void func(void);
class space_class
{
};//空间的成员可以是声明或者定义.
} //不以分号结束.
namespace space{
void func(void)
{
}
int i = 0;
} /*可以不连续,空间是可累积的,可以分散在多个文件中.*/
或者可以如下定义func;
xxx.cc
void space::func(void)
{
}
使用::访问空间space成员或者使用using声明.
using namespace space; 或者using space::成员.
namespace space
{
int i = 1;
namespace nested_space
{
int i = 0; //屏蔽space成员名字
int j= 0;
}
int b = j; /* error, 'j' : undeclared identifier不能直接使用nested_space成员,必须通过nested_space::i. */
int b = nested_space::j; //OK
}
int i = space::nested_space::I;
namespace nickname_space = space; //别名
namespace nested_nickname_space = space::nested_space;
在定义时未命名, 未命名的命名空间的定义局部于特定文件,不跨越其他文件.
1 namespace space{
2
3 namespace{
4
5 //只在包含该space中可见.
6
7 }
8
9 }
10
11 namespace space{
12
13 int i = 1;
14
15 namespace{
16
17 int i = 0; //error
18
19 int j= 0;
20
21 }
22
23 int a = i; /*error, 'i' : ambiguous symbol, 未命名空间的成员名字不可与外围空间相同. */
24
25 int b = j; //ok,未命名空间,所以直接访问.
26
27 }
28
29 int c = space::j; //访问未命名空间中的成员.
class parent1: public grandfather1
{
}
class son: public parent2, public parent1
{
son(): parent1(), parent2() {…} //构造所有的基类,按照继承顺序
~ son() {…} //按照构造的逆顺序.
};
如果parent1和parent2都定义了func()而son未定义func(),则
son obj;
obj.func(); //ambiguous.
obj.parent1::func(); //ok
1 class grandfather
2
3 {
4
5 grandfather){}
6
7 }
8
9 class patent1: public vitrual grandfather
10
11 /*virtual, 虚继承,对于给定虚基类grandfather,无论该类在派生层次中作为虚基类出现多少次,只继承一个共享的基类子对象,如果其他类继承patent1,patent2,派生类中只出现公共基类grandfather的一个副本.*/
12
13 {
14
15 patent1():grandfather(){}
16
17 };
18
19
20
21 class patent2: virtual public grandfather
22
23 {
24
25 patent2(): grandfather() {…}
26
27 };
28
29
30
31 class son: public patent1, public patent2
32
33 {
34
35 son(): grandfather(), //初始化虚基类
36
37 patent1(), //patent1中忽略grandfather的构造
38
39 patent2() //patent2中忽略grandfather的构造
40
41 /*构造函数的顺序是,虚基类按照继承顺序,之后非虚基类按照继承顺序,析构函数与构造函数相反.*/
42
43 {
44
45 …
46
47 }
48
49 };
allocator类是一个模板,提供类型化的内存分配以及对象构造与撤销.
allocator<T> a; //可以构造T类型的对象
a.allocate(n); //非配原始的未构造内存以保存T类型的n个对象, 返回指向分配的空间第一个T的指针.
a.deallocate(p, n); //释放内存, 在名为p的T*指针中包含的地址处保存T类型的n个对象.
a.construct(p, t); //在T* P处创建一个对象, T的复制构造函数用t初始化该对象
a.destroy(p); //析构p所指向的T对象
uninitialized_copy(b, e, b2); /*将迭代器[b, e]范围元素复制到b2开始的未构造的原始内存中(是构造而不是赋值)*/
uninitialized_fill(b, e, t); /*标准库copy的特殊版本将[b, e]中元素初始化为t,使用的是复制构造函数.*/
uninitialized_fill_n(b, e, t, n); /*将[b, e]中至多n个元素初始化为t,使用的是复制构造函数.*/
operator new & operator delete
string *ps = new string("hello"); /*new calls operator new to allocate space, then call construct, return point to new object*/
delete ps; /*delete calls descontruct, then call operator delete to deallocated space */
typeid: 返回type_info类,默认构造函数和复制构造函数为private,所以不能定义type_infor对象,只能通过typeid返回,具有 t1==t2, t1!=t2, t1.name() //返回c风格字符串, t1.before(t2) //如果t1出现在t2之前,返回true,befor强制的次序与编译器有关.
typeid (*p); 如果p定义了至少一个虚函数,则在运行时计算类型,如果p为动态指针,p值为0,则typeid(*p)抛出一个bad_typeid异常,如果p无定义任何虚函数,则结果与p的值不相关,返回的是p的静态类型.
dynamic_cast: 将基类类型的指针或引用安全地转换为派生类型的指针或引用,如果转换到指针类型的dynamic_cast失败,返回0,如果转换到引用类型的dynamic_cast失败,则抛出一个bad_cast类型的异常.
dynamic_cast<derived *>(baseptr);
dynamic_cast<derived &>(baseobj);
5.5.1 独立于外围类
xxx.h
1 template<class type> class myclass
2
3 {
4
5 private:
6
7 int m_i;
8
9 class nested_class
10
11 {
12
13 nested_class();
14
15 void func(const type &);
16
17 void func2()
18
19 {
20
21 int a = m_i; //可以直接使用外围类的成员.
22
23 }
24
25 };
26
27 };
28
29
xxx.cc
template<class type> outclass<type>::nested_class::nested_class()
{
}
xxx.h
1 template<class type> class outclass
2
3 {
4
5 private:
6
7 class nested_class;
8
9 };
10
11 template<class type> class outclass<type>::nested_class
12
13 {
14
15 public:
16
17 nested_class();
18
19 void func(const type &);
20
21 };
xxx.cc
1 template<class type> outclass<type>::nested_class::nested_class()
2
3 {
4
5 }
当前只有一个成员有值,其他成员变成未定义的.
默认情况下,表现类似struct,但是不能作为基类,成员函数不能为虚函数,不能具有静态数据成员和引用成员,不能具有定义了构造函数,析构函数或赋值构造函数的类类型的成员.
1 union unionname
2
3 {
4
5 myclass obj; //error
6
7 static int is; //error
8
9 int &rfi; //error
10
11 int i; //ok
12
13 char c; //ok
14
15 myclass * pobj; //ok
16
17 };
18
19 unionname obj = {1};
20
21 obj.c = 'a';
5.6.1 嵌套联合
1 class outclass
2
3 {
4
5 union unionname
6
7 {
8
9 int i;
10
11 } unionval;
12
13 };
14
15 outclass obj;
16
17 obj. unionval.i;
1 class outclass
2
3 {
4
5 //如果外围定义与union相同的成员名,屏蔽union成员.
6
7 union
8
9 {
10
11 int i; //不能有私有成员和受保护成员,也不能有成员函数.
12
13 };
14
15 };
16
17 outclass obj;
18
19 obj.i;
5.7 局部类
局部类:在函数体内定义的类.所有成员必须定义在类定义体内部,所以不允许声明static数据成员.
1 void func(void)
2
3 {
4
5 class localclass
6
7 {
8
9 public:
10
11 localclass(): m_i(0) {}
12
13 int get()
14
15 {
16
17 return m_i;
18
19 }
20
21 private:
22
23 int m_i;
24
25 };
26
27 }
C++程序有时候需要使用其他语言,使用链接指示只出任意非C++函数所用的语言.
1 extern "c" size_t strlen(const char *); //C不支持重载,所以不可链接多个相同名字函数.
2
3 extern "c" //链接指示必须放在全局域中.
4
5 {
6
7 int strcmp(const char*, const char*);
8
9 size_t strlen(const char*);
10
11 #include <string.h>
12
13 }
通过对函数定义使用链接指示,可以将函数导入到其他语言.
1 extern "c" double func(void) {//func函数定义体}
2
3 extern "c" void (*pf1)(int);
4
5 void(*pf2)(int);
6
7 pf2 = pf1; //error, 'c' : illegal linkage specification,C函数指针和C++函数指针具有不同类型
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?