我有几个派生类(例如 DerivedX
,其中 x 是派生类编号),它们在字段和成员函数方面有所不同。
我想用一些属性集扩展每个派生类(可以组织为字段 Extension ex
),保留每个 DerivedX
类。后者意味着,我们可以创建不包含属性 Extension ex
的“清晰”DerivedX
对象。
派生对象是在某些代码位置创建的(例如,在函数 main()
中),如果它们具有扩展功能,则应使用此功能(get、set、其他方法)从 main()
调用。
第一个想法是将此新属性添加到每个派生类,从而为每个派生类形成新类 (ExtendedX
)。但是我感觉代码会变得笨重,看来这种做法不好:
class Base
{
protected:
int b;
...
}
class Derived1: public Base
{
protected:
int d1;
...
};
class Derived2: public Base
{
protected:
int d2;
...
}
...X classes defined
class Extended1: public Derived1
{
protected:
Extension ex;
public:
int getExProperty1(){return ex.getProperty1();} // the realization could differ: we could also return copy of Extension object, pointer, set every field separately or the whole Extension object
}
class Extended2: public Derived2
{
protected:
Extension ex;
public:
int getExProperty1(){return ex.getProperty1();} // the realization could differ: we could also return copy of Extension object, pointer, set every field separately or the whole Extension object
}
...X classes defined
在那种情况下,要求的功能在每个类中重复。这是非常不推荐的做法。
另一个(第二个)想法是声明包含所考虑属性的“类扩展”(示例中的“Extension ex”
)并按需创建其对象以及类 DerivedX
,当我们需要 DerivedX
对象拥有这个属性时。
第三个想法是将指向 Extension
的指针作为基类的字段包含在内,并在我们不想使用扩展功能时将其简单地初始化为 NULL。但是,我们如何从 main()
中调用 Extension
类的方法呢?
future 扩展的功能也可能会有所不同(派生类根据要解决的问题类型进行扩展),这就是为什么第二个和第三个想法也比第一个更好。
有什么好的解决方案可以为多个派生类添加属性和功能包吗?
编辑1: 按照 Deduplicator 的建议,我尝试通过 CRTP 实现 mixin。 但是,代码失败:
«class Base» has no member named «getProperty1»
«class Base» has no member named «setProperty1»
代码:
#include <iostream>
using namespace std;
class Base {
int a;
public:
virtual ~Base(){}
};
class Derived1: public Base
{
public:
virtual ~Derived1(){}
};
template <class T> class Extension: public T
{
int prop1;
public:
void setProperty1(int _p){prop1=_p;}
int getProperty1(){return prop1;}
};
int main()
{
Base* der = new Derived1();
Base* e = new Extension<Derived1>();
e->setProperty1(10);
cout<< e->getProperty1();
delete der;
delete e;
return 0;
}
改变
e->
到
static_cast<Extension<Derived1> *>(e)->
使代码工作。
如何在这种情况下正确使用 Extension
类对象?
最佳答案
使用 CRTP:
// Classes implementing additions
template<class T> class Extended : public T /*, potentially additional bases */ {
// Common extension here.
}
关于C++03 : Add fields to several derived classes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27349308/