我有一个派生类,我希望能够使用copy构造函数构造它的参数是基类的实例。
我确信这在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 ++中应该合法。我需要明确的转换声明吗?
答案 0 :(得分:1)
您自己在做什么并没有多大意义,因为Base
不是Derived
的子类型,因此不能用作它的替换/替代,但是您可以尝试通过编写一个转换构造函数使其具有某种意义(与任何其他类型的初始化相同):
class Derived : public Base
{
public:
Derived(const Base &bs) : Base(bs), b("constructed from base") {}
protected:
std::string b;
};
这将首先初始化Derived
中的Base
bs
部分,然后使用一些值初始化字符串b
(尽管您可以将其保留为空白)默认初始化为空字符串。
答案 1 :(得分:0)
是的,您需要明确地从Base
强制转换为Derived
。每辆梅赛德斯都是汽车,但并不是每辆车都是梅赛德斯。
答案 2 :(得分:0)
有一个解决此问题的简单方法:通过将Base
构造函数拉到Derived
的范围内。
这可以通过using
语句完成:
class Derived : public Base
{
public:
using Base::Base; // Pulls in the Base class constructors into the scope of Derived
...
};
答案 3 :(得分:0)
此语句Derived derived(base);
或为简化B b(A());
进行类型A
到类型B
的隐式转换,仅当class B
直接继承或继承时才合法。间接来自Class A
。
为什么?因为class B
可能包含新信息,所以在您的情况下,string b
和强制类型转换不会“附加”信息。
答案 4 :(得分:0)
我找到了想要的东西(我不记得这个名字,所以之前也无法在Google上搜索它)。但是由于我正在使用继承,因此该技术实际上不起作用。 (或者至少我不知道如何使它工作。)
类型转换运算符:
Base::operator Derived()
{
Derived derived;
derived.a = a;
return derived;
}
这实际上并不编译,因为编译器不知道Derived
是什么。 (由于Derived
继承自Base
。)我不知道是否可以通过分离编译单元来完成这项工作。