gpt4 book ai didi

c++ - 从多个组件构建一个 C++ 类

转载 作者:太空狗 更新时间:2023-10-29 20:04:49 26 4
gpt4 key购买 nike

我正在开发一个系统,其中我有可以按层次顺序堆叠的矩形。所以基础是这样的:

Rect parent;
Rect child;
parent.addChild(&child);
...
Rect* someChild = parent.getChildAt(1);

到目前为止很容易实现。但是这些矩形应该能够实现不同的功能。这可能是一个 Serializer、Styler、Drawer 等...

现在我知道多重继承是一种“不行”,但在这种情况下,我会发现像这样的语法是可取的:

class StackableStyleableRect: publicRect, public Stackable, Styleable{}
class StackableStyleableDrawableRect: public Rect, public Stackable, Styleable, Drawable{}

我偶然发现了奇怪的重复出现的模板模式 (crtp),如果我理解正确的话,它将使上述成为可能。像这样:

class Rect{
public:
float width;
float height;
}

template <class RectType>
class Stackable{
public:
void addChild(RectType* c){
children.push_back(c);
}
std::vector<RectType*> children;
}

template <class RectType>
class Drawable{
public:
virtual void draw(){
RectType* r static_cast<RectType>(this);
drawRect(r->width, r->height);
}
}

template <class RectType>
class Styleable{
public:
int r, g, b;
}

class CustomRect: public Rect, public Stackable<CustomRect>, public Drawable<CustomRect>{
}

class CustomRectWithStyle: public Rect, public Stackable<CustomRect>, public Drawable<CustomRect>, public Styleable<CustomRect>{
public:
}

这样做的原因是我想重用不同种类的 Rect 类型的代码。在一个项目中,我不必为它们设置样式,而在另一种情况下,我需要提供的所有功能。通过这种方式来选择所需的功能,它可以使事情变得干净,也可以分离功能。

我对此做了一些基本测试,它按预期工作,但我觉得语法可能会随着时间的推移变得过于复杂。

此外,在某些时候,使组件相互依赖或在组件存在时使它们表现不同会很有用。 (例如,如果存在,Drawable 的绘制函数可以自动使用来自 Styleable 的颜色)

现在我注定迟早会遇到麻烦,还是它会奏效?有没有更适合的不同模式?还是根本不可能在“适当的”C++ 中做这样的事情?

最佳答案

首先,

我不会假装自己是额外的 C++ 专家。

多重继承并非“不行”

(否则它将被排除在语言之外)。多重继承是个问题,应该小心使用。你应该明白,你在做什么,在使用它的时候。

在您的情况下,您遇到 diamond problem 的可能性不大,这是多重继承的罪恶。

递归模板模式允许您在编译时检查启用的功能,就像这样

#define FEATURED(FEATURE, VALUE) \
template <template<class>class Feature = FEATURE> \
typename std::enable_if<std::is_base_of<Feature<RectType>, RectType>::value == VALUE>::type

template <class RectType>
class Styleable;

template <class RectType>
class Drawable{
public:

FEATURED(Styleable, true)
drawImpl()
{
std::cout << "styleable impl\n";
}

FEATURED(Styleable, false)
drawImpl()
{
std::cout << "not styleable impl\n";
}


virtual void draw(){
drawImpl();
}
};

您可以通过普通继承在功能上实现类似的功能,但似乎无法进行编译时功能检查。

另一方面,使用 crtp 会使您的代码变得更加复杂,并且您必须在头文件中实现所有内容。

总结,

我认为它很复杂,你应该确定你确实需要它。它会工作一段时间,直到它像任何其他代码一样被重新设计。它的生命周期主要取决于您对任务的理解。

关于c++ - 从多个组件构建一个 C++ 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16876550/

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