如何仅仅为了功能做多重继承?
- 必须共享基类的数据
- 没有虚函数(假设 vtable 很昂贵)
- 避免虚拟继承
- 实现必须能够驻留在 .cpp 中
- 允许使用 c++14
这里有类似的问题:-
- Multiple inheritance in diamond shape with functions only - 使用虚拟继承。虚拟继承是generally bad和 expensive .
- multiple inheritance without virtual inheritance - 侧重于语法和编译而不是编程技术。
- Multilevel inheritance in c++ (CRTP) , CRTP and multilevel inheritance , Eliminate redundancy with CRTP and multiple inheritance (C++03) 和 Using CRTP with virtual inheritance - 实现必须在标题中
这是一个示例代码(coliru demo):-
class O{
protected: int database=0;
};
class A : public O{
public: void print(){
std::cout<<database<<std::endl;
}
};
class B : public O{
public: void set(int s){
database=s+1;
}
};
class AB : public O{
public: void print(){//duplicate
std::cout<<database<<std::endl;
}
public: void set(int s){//duplicate
database=s+1;
}
};
//AB ab; ab.set(1); ab.print(); // would print 2
这是我的尝试 ( wandbox demo )。我滥用 CRTP :(
:-
class O{
public: int database=0;
};
template<class T>class OA{
public: void print(){
std::cout<<static_cast<T*>(this)->database<<std::endl;
}
};
template<class T>class OB{
public: void set(int s){
static_cast<T*>(this)->database=s+1;
}
};
class A :public O,public OA<A>{};
class B :public O,public OB<B>{};
class AB :public O,public OA<AB>,public OB<AB>{};
可以用,但看起来不够优雅。
此外,实现必须在 header 中(因为OA
和OB
是模板类)。
有更好的方法吗?或者这是要走的路吗?
对不起,如果这个问题太新手或已经问过。我是 C++ 初学者。
编辑
Give extended example of using please.
在 ECS 中,它在某些情况下很有用:-
class O{
protected: EntityHandle e;
};
class ViewAsPhysic : public O{ //A
public: void setTransform(Transformation t){
Ptr<PhysicTransformComponent> g=e;
g->transform=t;
}
};
class ViewAsLight : public O{ //B
public: void setBrightness(int t){
Ptr<LightComponent> g=e;
g->clan=t;
}
};
class ViewAsLightBlock : public O{ //AB
//both functions
};
最佳答案
这里的问题是 database
字段是类 O 的成员。因此如果没有虚拟继承,A 和 B 将各自拥有自己的 database
拷贝。所以你必须找到一种方法来强制 A 和 B 共享相同的值。例如,您可以使用在 protected 构造函数中初始化的引用字段:
#include <iostream>
class O{
int _db;
protected: int &database;
O(): database(_db) {};
O(int &db): database(db) {};
};
class A : public O{
public: void print(){
std::cout<<database<<std::endl;
}
A() {} // public default ctor
protected: A(int& db): O(db) {}; // protectect ctor
};
class B : public O{
public: void set(int s){
database=s+1;
}
B() {} // public default ctor
protected: B(int& db): O(db) {}; // protectect ctor
};
class AB : public A, public B {
int _db2;
public: AB(): A(_db2), B(_db2) {}; // initialize both references to same private var
};
int main() {
AB ab;
ab.set(1);
ab.print();
return 0;
}
按预期显示:
2
以上代码没有使用虚继承,没有虚函数,也没有模板,所以方法可以安全地在cpp文件中实现。 AB 类实际上使用了其父类的方法,并且对其基础数据仍然有一个连贯的 View 。事实上,它通过在最派生类中构建公共(public)数据并通过其父类中的 protected 构造函数注入(inject)来模拟显式虚拟继承。
关于c++ - 仅功能的多重继承 - 没有虚拟和 CRTP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45412092/