我的问题与以下结构有关:
抽象级别仅用于提供“真实”类(D1和D2)的成员函数。由于需要高度优化,因此没有虚拟性(抽象级别的析构函数受到保护)。在下列情况下,带有B0-C1-C2-D1的部件是否完全正常:
B0,C1和C2的成员函数有不同的名称吗?
C1和C2有一个同名的功能(例如myFunction
)?
C1和C2和D1有一个同名的功能(例如myFunction
)?
B0和C2的功能名称相同但不是C1(例如myFunction
)?
在每种情况下,D1将调用哪个版本的函数?
编辑:一段快速的代码来说明:
template<class CRTP> class A0
{
public:
void myfunction1();
protected:
~A0();
double mymember;
};
template<class CRTP> class B0 : public A0<CRTP>
{
public:
void myfunction2();
protected:
~B0();
};
template<class CRTP> class C1 : public B0<CRTP>
{
public:
void myfunction3();
protected:
~C1();
};
template<class CRTP> class C2 : public B0<CRTP>
{
public:
void myfunction4();
protected:
~C2();
};
class D1 : public C1<D1>, public C2<D1>
{
public:
void myfunction5();
};
答案 0 :(得分:0)
“完美确定”有些主观,但所有情况都在语言中明确定义。
您可能会遇到D1
中diamond inheritance的问题。 如果合适,您可以使用virtual inheritance让C1
和C2
从公共基础继承。这并不总是合适的,我们难以猜测。
1)
他们是使用不同方法的不同类,没有冲突。
2)
C1
或C2
内没有问题,但D1
会有问题。
3)
您将 在D1
中定义它。继承的myFunction
调用将从外部隐藏(无法访问)。您可以在D1中调用它们,如下所示:
struct D1 {
void myFunction() {
C1::myFunction();
C2::myFunction();
}
}
使用CRTP这样做会很烦人。我建议在类定义中使用typedef来保留你的理智。
4)
C1
将具有B0
赋予它的任何功能。如果它们不可访问,那么如果引用它们将会出现编译器错误。
老实说,我建议不要使用这种设计。将所有东西分解成小的具体物体并组成它们。保持这不是一个项目,它将是一个职业。
答案 1 :(得分:0)
我不会说没关系,除非您在课堂上两次A0
和B0
,但它们是不同的班级(B0<C1>
和B0<C2>
) 。除非你做一些专业化,否则很可能是not what you want。
对此的可能解决方案是something like this,它会删除多重继承:
template<class CRTP, class Base = B0<CRTP> > class C1 : public Base
{
public:
void myfunction3();
protected:
~C1();
};
template<class CRTP, class Base = B0<CRTP> > class C2 : public Base
{
public:
void myfunction4();
protected:
~C2();
};
class D1 : public C2<D1,C1<D1>>
{
public:
void myfunction5();
};
那么,如果你想在那里拥有那颗钻石,你可以在没有多个基类实例的情况下做到这一点吗?
不,因为
a)正如我所说的基类不同而且
b)在C ++中,虚拟继承仅适用于具有vtable的类。