具有引用和const成员的类的编译器生成的复制/赋值函数

时间:2014-04-21 20:52:05

标签: c++ compiler-construction copy-constructor assignment-operator

我正在阅读的书中说,当你的类包含一个引用或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对象自动生成复制构造函数,而不是赋值运算符?或者我可能只是没有正确理解这本书?有什么想法吗?

2 个答案:

答案 0 :(得分:4)

这本书错了。 const成员或参考成员将 禁止生成默认的复制赋值运算符,但是 不会阻止编译器生成复制构造函数。

答案 1 :(得分:3)

请勿尝试在此处学习特殊规则。

编译器生成的特殊成员函数的默认版本遵循一个简单的模式:

  • 为每个子对象(基类和成员)调用适合类型的特殊成员函数。

由此,你可以解决每一个案例。

int i;
int &ri1 = i;
int &ri2 = ri1;
允许

,因此允许复制包含int&的对象。

引用没有赋值运算符(ri2 = ri1;不重新引用引用),因此不允许赋值。

引用不能默认构造:

int& ri; // error

所以包含int&的类型不能默认构造。

一个重要的考虑因素是对编译器默认代码进行访问检查,就像您自己编写代码一样。因此,如果基类具有私有拷贝构造函数,那么有趣的事情就会发生......并且您不必为其中任何一个学习特殊规则。