如果没有提供任何构造函数,编译器将提供一个没有任何参数,不执行任何操作的默认构造函数.
只能有一个默认构造函数.
带参数的构造函数也可以是默认构造函数,只要所有参数都有默认值
用于将一个对象复制到新创建的对象中,它用于初始化过程而不是常规的赋值过程.类似构造如下:
Class_name (const Class_name &);
她接受一个指向类对象的常量引用作为参数.
调用时机 : 新建一个对象并将其初始化为同类的现有的对象的时候,复制构造函数将被调用.
Class StaingBad;
StringBad ditto(motto);
StringBad metto = motto;
StringBad also = StringBad(motto);
StringBad *string = new StringBad(motto);
每当程序生成对象副本时都将使用复制构造函数,具体的说: 当函数按值传递时或函数返回对象时都将使用复制构造函数.
默认复制构造函数逐个复制非静态成员(静态成员不需要,静态成员属于整个类而不是对象),称为成员复制或者浅复制
StringBad sailor = motto;
//等价于
StringBad sailor;
sailor.str = motto.str;
sailor.len= motto.len;
深度复制和浅复制
深度复制: 如 果类中包含了使用new初始化的指针成员, 应当定义一个复制构造函数,以 复制指向的数据,
浅复制: 浅 复制仅浅浅地复制指针信息, 而不会深入“ 挖掘” 以复制指针引用的结构。
c++允许类对象赋值,通过重载 ’ = ’ 运算符实现 . 将已有的对象赋给另一个对象时将使用重载的赋值运算符.
赋值运算符的隐式实现也对成员进行逐个复制。 如果成员本身就是类对象, 则程序将使用为这个类定义的赋值运算符来复制 该成员.
赋值 操作并不创建新的对象.在赋值时需要注意:
StringBad &StringBad ::operator =(const StringBad &st){
if(this == st)
return *this;
delete []str;
len = st.len;
str = new char [len+1];
std::strcpy(str,st.str);
retrurn *this.
}
在重载 时, C++ 将 区分常量 和非常量函数 的特征标, 因此可以提供一个仅供 const String对象使用的operator 版本:
.
char & String::operator[](int i){
return str[i];
}
const char & String::operator[](int i)const
{
return str[i];
}
可以 将成员函数 声明为静态的( 函数声明必须包含关键字 static, 但如 果函数定义是独立 的, 则其中不能包含关键字 static),
不能 通过对象调用静态成员 函数; 静态成员函数不能 使用 this 指针。 如果 静态成员函数是在公有部分声明 的, 则可以 使用 类名和作用域解析运算符来调用它。
NULL、 0 还是nullptr: 以前,空指针可以用 0 或 NULL( 在很多头文件中, NULL 是 一个 被定义 为 0 的符号常量) 来表示。 C 程序员通常使用NULL 而不是 0, 以指出这是一个指针, 就像使用‘\ 0’ 而 不是 0 来表示空字符, 以指 出这是一个字符 一样。C++ 传统上 喜欢用简单的0 , 而不是等价 的 NULL。 但正如前面 指出 的, C++ 11 提供了关键字nullptr,这是 一种更好的选择。
可以提高效率. 如果函数返回(通过调用对象的方法或将对象作为参数) 传递给它的对象,可以通过返回引用来提高其效率。
两种常见的 返回 非 const 对象情形是, 重载赋值运算符以及重载与cout 一起使用 的<< 运算符。 前者这样做旨在提高效率, 而后者必须这样做。
如果被返回的对象是被调用函数中的局部变量, 则不应按引用方式返回 它, 因为在被调用 函数 执行 完毕 时, 局部对象将 调用其析构 函数。 因此, 当控制权回到调用函数时, 引用 指向的对象 将不再存在。 在这种情况下,应返回对象而不是引用。
在设计类时可以看看原书第12章最后的几个案例.