第二章 构造函数语意学(the semantics of constructors)
2.1 Default Construcor 的建构操作
有四种情况,会导致“编译器必须为未声明constructor 之class 合成一个 Default constructor ”. C++ Stardand 把那些合成物称为implicit nontrivial default constructor .被合成出来的的constructor 只能满足编译器(而非程序)的需求。它之所以能够完成任务,是借着“调用member object 或 base class 的default constructor ”或是“为每一个object 初始化其virtual function 机制或virtual base class 机制” 而完成。至于没有存在那四种情况而又没有声明任何constructor 的classes ,我们说它们拥有的是 implicit trivial constructors, 它们实际上并不会被合成出来。
在合成的default constructor 中,只有base class subobjects 和 member class objects h会被初始化。所有其它的nonstatic data member ,如整数、整数指针、整数数组等等都不会被初始化。这些初始化操作对程序而言或许有需要,但对编译器则并非必要。如果程序需要一个“把某指针设为0”的default construct, 那么提供它的人应该是程序员。
C++新手一般有两个常见的误解:
1. 任何class 如果没有定义default constructor ,就会被合成出一个来。
2. 编译器合成出来的default constructor 会明确设定“class 内每一个data member 的默认值”。
2.2 Copy constructor 的建构操作
是一种特殊构造函数,具有单个形参,该形参(常用CONST修饰)是对该类类型的引用。当定义一个新对象并用一个同类型的对象对它进行初始化时,将显式使用拷贝构造函数。当将该类型的对象传递给函数或从函数返回该类型的对象时,将隐式使用拷贝构造函数。
合成的拷贝构造函数:
即使我们定义了其他构造函数,也会合成拷贝构造函数。合成拷贝构造函数的行为是,执行逐个成员初始化(memberwise initialize),将新对象初始化为原对象的副本。
所谓“逐个成员”,指的是编译器将现有对象的每个非static 成员,依次复制到正创建的对象。只有一个例外,每个成员的类型决定了复制该成员的含义。合成拷贝构造函数直接复制内置类型成员的值,类类型成员使用该类的拷贝构造函数进行复制。数组成员的复制是个例外。虽然一般不能复制数组,但如果一个类具有数组成员,则合成拷贝构造函数将复制数组。复制数组时合成拷贝构造函数将复制数组的每一个元素。
注意:按位拷贝不会分配新的内存空间而只是简单地将该地址的值复制给另一个指针,所以就会出现两个指针指向同一块内存区域。
不要Bitwise Copy Semantics!
什么时候一个Class 不展现出“Bitwise Copy Semantics”呢?有四种情况:
1. 当class 内含一个member object 而后者的class 声明有一个copy constructor 时
2. 当class 继承自一个base class 而后者存在存在有一个copy constructor 时(再次强调,不论是被明确声明或是被合成而得)。
3. 当class 声明一个或多个 virtual function 时。
4. 当class 派生自一个继承串链,其中有一个或多个virtual base classes时。
posted on 2008-05-23 09:04
Macaulish 阅读(1737)
评论(2) 编辑 收藏 引用