构造函数的调用:
1. 在初始化时调用(构造函数)
(合成拷贝构造函数+重载赋值运算符)
“合成拷贝构造函数”,同时对所有成员进行一次“普通赋值”操作,此时只相当于
进行内存复制。若需要复制指针指向的内容(如成员是一个链表),那么必须
选择定义
i. (类的)拷贝构造函数 或
ii.(类成员的)重载复制运算符
通常情况下,我们选择ii.,定义(类成员的)重载赋值运算符,同时缺省地选用
(类的)合成拷贝构造函数。因为类成员是更底层的类,因此复用率将更高。
更一般地,对最底层的类定义完整的“构造函数”,“拷贝构造函数”,“重载赋值运算符”
和“析构函数”,那么更高层的类即可应用缺省的合成拷贝构造函数和缺省的赋值运算符
对其成员进行直接调用了。
析构函数的调用:
1. 可行域结束时调用
函数(而是调用合成拷贝构造函数),但是仍会调用析构函数,造成不对称调用。
因此函数的形参是一个类的实例时,一定要记得定义拷贝构造函数。
1. 在初始化时调用(构造函数)
String str("some text.");
2. 在类型转换时调用(转换构造函数)
String str = String("some text.");
3. 在隐式类型转换作传值函数实参时调用(隐式构造函数)
<pre name="code" class="plain">void Print(String str)
{
printf("%s\n", str.m_str);
}
Print("auto print.");
拷贝构造函数的调用:
1. 拷贝构造函数缺省时,在拷贝初始化时调用(合成拷贝构造函数)String stra("string");
String strb = stra;// 等同于对所有成员变量进行一次赋值操作。
2. 拷贝构造函数已定义时,在拷贝初始化时调用(拷贝构造函数)
String stra("string");
String strb = stra;// 调用定义的拷贝构造函数。
3. 函数的形参是一个类的实例时,在函数入口时调用(拷贝构造函数)
void Print(String str)// 调用定义的拷贝构造函数。
{
printf("%s\n", str.m_str);
}
String stra("auto print.");
Print(stra);<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
重载赋值运算符的调用:
1. 在重载赋值运算符已定义时,拷贝构造函数缺省时,在拷贝初始化时调用(合成拷贝构造函数+重载赋值运算符)
String stra("string");
String strb = stra;// 等同于对所有成员变量进行一次重载赋值运算符操作。
2. 在重载赋值运算符已定义时,在赋值时调用
String stra("string");
String strb("some text.");
stra = strb;// 调用重载赋值运算符
strb = "string";// 调用重载赋值运算符
注意:如果拷贝构造函数和重载赋值运算符都缺省,那么拷贝初始化时将调用
“合成拷贝构造函数”,同时对所有成员进行一次“普通赋值”操作,此时只相当于
进行内存复制。若需要复制指针指向的内容(如成员是一个链表),那么必须
选择定义
i. (类的)拷贝构造函数 或
ii.(类成员的)重载复制运算符
通常情况下,我们选择ii.,定义(类成员的)重载赋值运算符,同时缺省地选用
(类的)合成拷贝构造函数。因为类成员是更底层的类,因此复用率将更高。
更一般地,对最底层的类定义完整的“构造函数”,“拷贝构造函数”,“重载赋值运算符”
和“析构函数”,那么更高层的类即可应用缺省的合成拷贝构造函数和缺省的赋值运算符
对其成员进行直接调用了。
析构函数的调用:
1. 可行域结束时调用
{
String stra("string");
}// 调用析构函数
2. 函数的形参是一个类的实例时,在函数返回时调用
void Print(String str)
{
printf("%s\n", str.m_str);
}// 调用析构函数
String stra("auto print.");
Print(stra);
注意:此时如果没有定义拷贝构造函数而定义了析构函数,那么将不会调用拷贝构造
函数(而是调用合成拷贝构造函数),但是仍会调用析构函数,造成不对称调用。
因此函数的形参是一个类的实例时,一定要记得定义拷贝构造函数。