【发布时间】:2018-04-12 10:49:13
【问题描述】:
假设我们有以下类:
class A
{
public:
A() {}
};
class B
{
public:
B() {}
virtual ~B() {}
};
template<typename T>
class BB: public B
{
public:
BB() {}
};
class C: public A, public BB<bool>
{
public:
C() {}
};
class D: public A, public B
{
public:
D() {}
};
将C 对象转换为类类型D 是否可能/允许/安全?这是为了访问非模板化的东西并使用多态性。
我试过并得到错误no matching function for call to 'D::D(C&)'。
添加构造函数D::D(C& c): A(c), B(c) {} 就足够了吗?
请注意,我目前正在使用 C++11,我必须坚持使用它,因此我需要一个兼容的解决方案,但是可能会有更好的解决方案与更高的标准,所以你仍然可以分享这些为了我的知识。
编辑:在阅读了 cmets 之后,这里对我的问题进行了一些进一步的解释
B 和 BB 的定义无法更改,就像 API 中无法修改的类一样。
直接铸造是调用构造函数并创建一个新对象,这不是我想要的,因此它需要答案中提到的间接。
鉴于这个其他类:
class Cbis: public A, public BB<float>
{
public:
Cbis() {}
};
D 类的唯一用途是允许将 C 和 Cbis 引用存储在同一个容器中,并且能够访问来自 A 和 B 类的方法。
最后,这可能根本不可能,因为即使有共同的祖先,D 不是基类。
因此,有什么替代方案?除了存储在两个单独的容器中,一个基于A 指针和B 指针。
【问题讨论】:
-
如果你将它实例化为
C,你不能期望它是D类型,因此不是有效的转换。 -
@Neijwiert 我会走得更远。并不是说您不能期望
C的实例也是D的实例,因为这意味着它可能是一个实例,但您不能确定。C的实例不是D的实例。 -
如果你的意图是创建新的值,而不是使用指针或引用,那么多态与它无关。就您提供的小细节而言,您采用了正确的方法。
-
我认为这是个好问题 -
C是 A,C是BB,D也是A,D是 @ 987654349@,最后一个BB是一个B。但这一切仍然不意味着C是D!另外,我建议先编译看看编译器是怎么说的。 -
同样遵循@JeromeReinländer,您可以通过
A和B继承C(仅,没有更多类)来大大简化这一点。A仍然无法转换为B,反之亦然。
标签: c++ templates inheritance polymorphism multiple-inheritance