【发布时间】:2019-05-14 20:49:18
【问题描述】:
我有一个派生类,我希望能够使用复制构造函数来构造它,其中参数是基类的实例。
我相信这在 C++ 中应该是可能的。这是一个例子:
#include <string>
class Base
{
public:
friend
void swap(Base& l, Base& r)
{
using std::swap;
swap(l.a, r.a);
}
Base()
: a{1}
{
}
Base(const int a)
: a{a}
{
}
virtual
~Base()
{
}
Base(const Base& base)
: a{base.a}
{
}
Base(Base&& base)
: Base()
{
swap(*this, base);
}
Base& operator=(Base base)
{
swap(*this, base);
return *this;
}
protected:
int a;
};
class Derived : public Base
{
protected:
std::string b;
};
int main()
{
Base base(2);
Derived derived(base);
}
错误(g++ main.cpp)是:
main.cpp: In function ‘int main()’:
main.cpp:71:31: error: no matching function for call to ‘Derived::Derived(Base&)’
class Derived derived(base);
^
main.cpp:57:7: note: candidate: Derived::Derived()
class Derived : public Base
^~~~~~~
main.cpp:57:7: note: candidate expects 0 arguments, 1 provided
main.cpp:57:7: note: candidate: Derived::Derived(const Derived&)
main.cpp:57:7: note: no known conversion for argument 1 from ‘Base’ to ‘const Derived&’
main.cpp:57:7: note: candidate: Derived::Derived(Derived&&)
main.cpp:57:7: note: no known conversion for argument 1 from ‘Base’ to ‘Derived&&’
因此编译器不知道如何将Base 的实例隐式转换为Derived。
我认为这在 C++ 中应该是合法的。我需要明确的转换语句吗?
【问题讨论】:
-
为什么这在任何语言中都应该是合法的?这与 Liskov 替换原则相反。
-
这是错误的:`class Base base(2);派生类派生(基); ` 只需使用:
Base base(2); Derived derived(base); -
没有隐式类型转换这样的东西。根据定义,强制转换是一种显式类型转换。
-
另请注意,没有单个虚函数的公共继承几乎总是一个错误,复制使用公共继承的对象也几乎总是一个错误。
标签: c++ inheritance casting copy-constructor