【发布时间】:2018-08-09 05:54:00
【问题描述】:
我想使用using关键字继承基类的复制构造函数:
#include <iostream>
struct A
{
A() = default;
A(const A &) { std::cerr << __PRETTY_FUNCTION__ << std::endl; }
A( A &&) { std::cerr << __PRETTY_FUNCTION__ << std::endl; }
A& operator=(const A &) { std::cerr << __PRETTY_FUNCTION__ << std::endl; return *this; }
A& operator=( A &&) { std::cerr << __PRETTY_FUNCTION__ << std::endl; return *this; }
};
struct B : A
{
using A::A;
using A::operator=;
B& operator=(const B &) { std::cerr << __PRETTY_FUNCTION__ << std::endl; return *this; }
B& operator=( B &&) { std::cerr << __PRETTY_FUNCTION__ << std::endl; return *this; }
};
int main()
{
A a;
B b;
b = a; // OK
B b1( a ); // compile error
B b2(std::move(a)); // compile error
return 0;
}
使用using 关键字继承赋值运算符可以正常工作,但继承复制和移动构造函数会导致编译错误:继承的构造函数不适合从相同或派生类型的表达式进行初始化 .
http://coliru.stacked-crooked.com/a/fe84b429c391c894:
main.cpp:16:14: note: an inherited constructor is not a candidate for initialization from an expression of the same or derived type
main.cpp:8:5: note: candidate: A::A(A&&)
A( A &&) { std::cerr << __PRETTY_FUNCTION__ << std::endl; }
^
main.cpp:16:14: note: inherited here
using A::A;
为什么我可以继承赋值运算符但不能继承复制构造函数?有什么区别?如果我也不能继承赋值运算符,我可以理解。但是相反地继承赋值运算符被认为是可以的。这对我来说有点奇怪。
故事
我想要的类似于this 问题中提出的问题:我只想向现有类添加新方法而不修改它(它是来自另一个库的类)。
http://coliru.stacked-crooked.com/a/149a6194717cd465:
#include <iostream>
struct A // not my class
{
};
struct B : A
{
using A::A;
using A::operator=;
void foo() { std::cerr << "fuu" << std::endl; }
};
A NotMyFunc()
{
return {};
}
int main()
{
B b(NotMyFunc());
b.foo();
return 0;
}
但我不想重新实现复制和移动构造函数。
【问题讨论】:
-
Pretty_Function 不是标准的。
-
@JiveDadson,但它仍然很漂亮。
-
不在我的编译器上。它不见了。
-
因为标准是这样说的。 “如果从基类引入派生类的构造函数或赋值运算符具有派生类(15.8)的复制/移动构造函数或赋值运算符的签名,则使用声明本身不会抑制隐式声明派生类成员;来自基类的成员被派生类的隐式声明的复制/移动构造函数或赋值运算符隐藏或覆盖”。
-
对不起,这是一个错误的理由!它不起作用,因为“具有 派生 类的复制/移动构造函数或赋值运算符的签名”。它适用于
A::A(const B&),但不适用于这种情况。正确的理由是here。请注意,它仅适用于构造函数,不适用于赋值运算符。
标签: c++ inheritance copy-constructor move-constructor