来自基础 class 的复制构造函数

Copy-constructor from base class

我有以下代码:

#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 cannot be copy-constructed (for return from make_b), because it has no copy-constructor, because A的复制构造函数被删除。


Does B(const A&) not qualify as copy-constructor, and what is the rule that applies here?

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

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

Does the copy and move constructor always have to take one argument of the same type (and not a superclass)?

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

Can it have additional parameters with default values?

是的。

To allow implicit copy and move construction, is it necessary to explicitly add copy and move-constructors B(const B&) and B(B&&)?

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

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

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

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

约 1 人: 在构造时,编译器会从最高位到当前构造的-class逐个调用所有基class。 如果C继承自B继承自A 编译器调用 A() 然后 B() 而不是 C() ctros 以构建 C 对象。

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

这里的问题是按值返回B,如果退出则调用move ctor,否则调用move ctor。你删除了两个