【问题标题】:Is the copy CTOR required even if never called?即使从未调用过副本 CTOR 是否也需要?
【发布时间】:2011-09-12 16:02:12
【问题描述】:

考虑以下几点:

class X {
public:
    X(int i) { cout << "X(int i)" << endl; }
    X(const X& x) { cout << "X(const X& x)" << endl; }
};

void main() {
    X x1(1);
    X x2 = X(1);
    X x3 = (X)1;
}

运行此代码会产生以下输出:

X(int i)
X(int i)
X(int i)

我认为以上三个语句都是等效的,因为永远不会调用副本 CTOR。但是,将X 的副本 CTOR 更改为私有:

class X {
public:
    X(int i) { cout << "X(int i)" << endl; }
private:
    X(const X& x) { cout << "X(const X& x)" << endl; }
};

将无法编译(在 Visual Studio 2010 中)并出现此错误:

cannot access private member declared in class 'X'

所以看起来复制 CTOR 以某种方式涉及,虽然我不太明白如何。

谢谢

【问题讨论】:

    标签: c++ copy-constructor access-modifiers


    【解决方案1】:

    Ist 对象使用您所知道的参数化构造函数,而所有其他对象都使用复制构造函数。即为什么当你让它发生私人访问冲突时。其他两个对象正在使用复制构造函数。

    这些是使用复制构造函数的方式。

    【讨论】:

      【解决方案2】:
      X x1(1);
      X x2 = X(1);
      X x3 = (X)1;
      

      原因是所有这些都不完全等价。

      第一个是直接初始化,第二个和第三个是复制初始化。复制初始化,复制构造函数必须是公共的,否则编译器会报错。

      现在的问题是,如果 2nd 和 3rd 要求 copy-ctor 是公开的,那么为什么会出现以下输出:

      X(int i)
      X(int i)
      X(int i)
      

      这肯定说明 copy-ctor 永远不会被调用,这是真的。编译器只是忽略了对 copy-ctor 的调用。根据 §8.5/14,在这种情况下,允许编译器消除调用复制构造函数的需要。这就是为什么你看不到 copy-ctor 被调用的原因。

      有点内部:在第 2 和第 3 种情况下,首先通过调用 X(int i) 创建一个临时文件,然后这个临时文件应该被传递给 copy-ctor 以复制初始化被声明的对象。但是编译器优化了这一步,省略了对 copy-ctor 的调用。

      【讨论】:

      • 如果您添加一些关于第二行和第三行的实际差异以及在什么情况下的信息会很有趣(在这种情况下根据 8.5/14...) 回答
      【解决方案3】:
      1. 这个:

        X x3 = (X)1; 是从int 转换为X 类型的对象的c 风格

      2. 本次抄袭:

        X x2 = X(1);

      已优化,但编译器仍需要访问复制构造函数。

      【讨论】:

        【解决方案4】:

        X x2 = ... 调用复制构造函数(即使编译器稍后对其进行优化)。因此,它必须仍然可以访问。

        【讨论】:

          猜你喜欢
          • 2019-09-13
          • 2016-11-27
          • 2016-09-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多