gpt4 book ai didi

c++ - 仅功能的多重继承 - 没有虚拟和 CRTP

转载 作者:行者123 更新时间:2023-11-30 02:24:23 25 4
gpt4 key购买 nike

如何仅仅为了功能做多重继承?

  • 必须共享基类的数据
  • 没有虚函数(假设 vtable 很昂贵)
  • 避免虚拟继承
  • 实现必须能够驻留在 .cpp 中
  • 允许使用 c++14

这里有类似的问题:-

这是一个示例代码(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 中(因为OAOB 是模板类)。

有更好的方法吗?或者这是要走的路吗?

对不起,如果这个问题太新手或已经问过。我是 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com