【问题标题】:Copy-constructor from base class来自基类的复制构造函数
【发布时间】:2015-03-08 12:39:32
【问题描述】:

我有以下代码:

#include <iostream>
#include <utility>

class A {
public:
    A() { }
    A(const A&, int i) { std::cout << "A copy" << std::endl; }
    A(A&&, int i) { std::cout << "A move" << std::endl; }
    A(const A&) = delete;
    A(A&&) = delete;
};

class B : public A {
public:
    B(int i) { std::cout << "B construct" << std::endl; }
    B(const A& a) : A(a, 1) { std::cout << "B copy" << std::endl; }
    B(A&& a) : A(std::move(a), 1) { std::cout << "B move" << std::endl; }
};


B make_b() {
    return B(1);
}

int main() {
    B b = make_b();
}

编译器报错B不能被复制构造的错误(用于从make_b返回),因为它没有复制构造函数,因为A的复制构造函数被删除了。


  • B(const A&amp;) 不符合复制构造函数的条件,这里适用的规则是什么?
  • 复制和移动构造函数是否总是必须采用相同类型的一个参数(而不是超类)?
  • 是否可以有带默认值的附加参数?
  • 能否对其进行模板化以便解析为有效的复制构造函数?
  • 要允许隐式复制和移动构造,是否需要显式添加复制和移动构造函数B(const B&amp;)B(B&amp;&amp;)

【问题讨论】:

  • 注: C++ 中的正确术语是“基类”而不是超类。

标签: c++ class c++11 copy-constructor


【解决方案1】:

B(const A&) 不符合复制构造函数的条件吗,这里适用的规则是什么?

没有。复制构造函数创建另一个相同类型的对象。 AB 的类型不同。如果您尝试从其基类的对象构造派生类的对象,您应该如何初始化派生类的成员?您从中复制的源对象没有要复制的成员!

此外,B 已经有一个复制构造函数,由编译器隐式声明,但是因为隐式定义格式不正确(因为基类 A 是不可复制的)它被编译器删除了,所以不能使用。

复制和移动构造函数是否总是必须采用相同类型的一个参数(而不是超类)?

不一定是一个参数,B(const B&amp;, int = 0) 是一个拷贝构造函数,因为它可以被调用来创建一个B 的拷贝。但B(const A&amp;) 不是复制构造函数。

是否可以有附加参数的默认值?

是的。

为了允许隐式复制和移动构造,是否需要显式添加复制和移动构造函数B(const B&amp;)B(B&amp;&amp;)

是的,您需要显式定义它们,因为编译器将使用的隐式定义不起作用。

由于您的派生类型没有任何成员,并且您已经拥有采用 A 的构造函数,您可以像这样定义它们:

B(const B& b) : B(static_cast<const A&>(b) { }
B(B&& b) : B(static_cast<A&&>(b) { }

这会创建委托构造函数,它只是将参数转发给您现有的构造函数(使用合适的基类型强制转换)。

【讨论】:

    【解决方案2】:

    大约 1 : 构造时,编译器从最高到当前构造的类,一一调用所有基类。 如果 C 继承自 B 继承自 A 编译器调用 A() 然后 B() 而不是 C() ctros 以构建 C 对象。

    复制构造函数也是如此: 在您的示例中,您调用了 A() 复制构造函数来构建对象的“A”部分,但您删除了它。

    这里的问题是按值返回 B,如果 exits 调用 first move ctor,如果没有则调用 move ctor。你都删除了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-01
      • 2018-10-29
      • 2013-06-23
      • 2012-01-30
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 2017-10-27
      相关资源
      最近更新 更多