gpt4 book ai didi

C++ 通过继承实现的基于组件的架构被认为是好的做法吗?

转载 作者:太空宇宙 更新时间:2023-11-04 11:30:07 25 4
gpt4 key购买 nike

当我有一个异构对象的容器时,我正在实现一个架构,这些对象可能有或没有一些通用的方法属性。我需要循环遍历它们并应用一些函数,更新一些成员,并通过各种接口(interface)调用一些方法。

我已经得出了我认为基于继承的“标准”架构:

#include <vector>
#include <memory>
#include <iostream>

using namespace std;

struct Base {
virtual ~Base() {}
};

struct PositionInterface {
int x = 0;
int y = 0;
virtual ~PositionInterface() {}
};
struct DrawInterface {
void draw() { cout << "Here i am" << endl; }
virtual ~DrawInterface() {}
};
struct ChargeInterface {
int charge = 100;
virtual ~ChargeInterface() {}
};
struct LifeInterface {
int life = 100;
virtual ~LifeInterface() {}
};

struct A: public Base,
public LifeInterface, public PositionInterface {};
struct B: public Base,
public DrawInterface, public PositionInterface, public ChargeInterface {};

int main() {
std::vector<std::shared_ptr<Base>> vec;
vec.push_back(make_shared<A>());
vec.push_back(make_shared<B>());

for (auto & el : vec) {
auto p = dynamic_cast<PositionInterface *>(el.get());
if (p) {
p->x += 10;
p->y -= 10;
}
}
// ..other stuff
for (auto & el : vec) {
auto l = dynamic_cast<LifeInterface *>(el.get());
if (l) {
l->life -= 100;
}
}
// ..other stuff
for (auto & el : vec) {
auto d = dynamic_cast<DrawInterface *>(el.get());
if (d) {
d->draw();
}
}
}

无论如何,我看起来也像一个基于组件的系统。在我看来,这些接口(interface)可能是通过组合而不是继承添加的组件。像这样:

struct A: public Base {
LifeInterface l;
PositionInterface p;
};

但是我怎样才能通过 Base 对象的 vector dynamic_cast 循环到正确的接口(interface)?

您是否发现这种架构有任何缺点(除了 RTTI 和公共(public)变量:-))?

最佳答案

"But then how could i cycle through the vector of Base objects dynamic_casting to the right interface?"

我建议使用真正的抽象接口(interface),像这样:

struct Base {
virtual ~Base() {}
};

struct PositionInterface {
virtual int x() const = 0;
virtual void x(int value) = 0;
virtual int y() const = 0;
virtual void y(int value) = 0;
virtual ~PositionInterface() {}
};

struct DrawInterface {
virtual void draw() const = 0;
virtual ~DrawInterface() {}
};

struct ChargeInterface {
virtual int charge() const = 0;
virtual ~ChargeInterface() {}
};

struct LifeInterface {
virtual int life() const {};
virtual ~LifeInterface() {}
};

可用作混合的基本实现类

class PositionBase : public PositionInterface {
public:
virtual int x() const { return x_; }
virtual void x(int value) { x_ = value; }
virtual int y() const { return y_; }
virtual void y(int value) { y_ = value; }
virtual ~PositionBase() {}

protected:
PositionBase() {}
int x_;
int y_;
};

class ChargeBase : public ChargeInterface {
public:
virtual int charge() const { return charge_; }
virtual ~ChargeInterface() {}

protected:
ChargeBase(int charge) : charge_(charge) {}
const int charge_;
};

class LifeBase : public LifeInterface {
public:
virtual int life() const { return life_; }
virtual ~LifeBase() {}

protected:
LifeBase(int life) : life_(life) {}
const int life_;
};

让你的实现如下

struct A 
: public virtual Base
, public LifeBase
, public PositionBase {
A() : Base(), LifeBase(100), PositionBase() {}
};

struct B
: public virtual Base
, public DrawInterface
, public PositionBase
, public ChargeBase {
B() : Base(), PositionBase(), ChargeBase(100)
virtual void draw() const {
// Must implement draw()
}
};
  1. 不要使用公共(public)成员变量,因为您无法从继承的类中真正控制它们。如上所示使用虚拟 getter/setter 函数。
  2. 要检查是否支持正确的接口(interface),请使用 dynamic_cast<> .要对这些执行操作,请提供简单的模板化函数,例如:

template<class T> void draw(const T& item) {
DrawInterface* drawableItem = dyn<mic_cast<DrawInterface*>(&item);
if(drawableItem) {
drawableItem->draw();
}
// Item isn't drawable, ignore or throw exception
}

关于C++ 通过继承实现的基于组件的架构被认为是好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25084962/

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