我正在阅读的书中说,当你的类包含一个引用或const的成员时,使用编译器生成的复制构造函数或赋值运算符将不起作用。例如,
#include <iostream>
#include <string>
using namespace std;
class TextBlock
{
public:
TextBlock (string str) : s(str) {
cout << "Constructor is being called" << endl;
}
string& s;
};
int main () {
TextBlock p("foo");
TextBlock q(p);
q = p;
cout << "Q's s is " << q.s << endl;
return(0);
}
根据我的书,TextBlock q(p);
和q = p;
这两行应该返回编译器错误。但是使用适用于Linux的g ++编译器,我只是为行q = p;
收到错误。当我对此进行评论时,这样可以正常工作并且代码可以编译。为Q输出正确的s,因此它显然是由编译器生成的复制构造函数复制的。当我将行string& s;
更改为const string s
时,我得到相同的结果。
是否对C ++进行了一些更改,现在允许为引用和const对象自动生成复制构造函数,而不是赋值运算符?或者我可能只是没有正确理解这本书?有什么想法吗?
答案 0 :(得分:4)
这本书错了。 const成员或参考成员将 禁止生成默认的复制赋值运算符,但是 不会阻止编译器生成复制构造函数。
答案 1 :(得分:3)
请勿尝试在此处学习特殊规则。
编译器生成的特殊成员函数的默认版本遵循一个简单的模式:
由此,你可以解决每一个案例。
int i;
int &ri1 = i;
int &ri2 = ri1;
允许,因此允许复制包含int&
的对象。
引用没有赋值运算符(ri2 = ri1;
不重新引用引用),因此不允许赋值。
引用不能默认构造:
int& ri; // error
所以包含int&
的类型不能默认构造。
一个重要的考虑因素是对编译器默认代码进行访问检查,就像您自己编写代码一样。因此,如果基类具有私有拷贝构造函数,那么有趣的事情就会发生......并且您不必为其中任何一个学习特殊规则。