问题描述
假设我有以下课程:
class BaseObject {
public:
virtual int getSomeCommonProperty();
};
class Object1: public BaseObject {
public:
virtual int getSomeCommonProperty(); // optional
int getSomeSpecificProperty();
};
class BaseCollection {
public:
virtual void someCommonTask();
};
class Collection1: public BaseCollection {
public:
virtual void someCommonTask(); // optional
void someSpecificTask();
};
从 BaseCollection 派生的每个集合都处理特定的对象类型(并且只有一种类型).但是 BaseCollection 应该能够执行一些对所有对象都通用的任务,只使用 BaseObject 中的通用对象属性.
Each collection, derived from BaseCollection, deals with a specific object type (and only one type). But BaseCollection should be able to perform some tasks that are common to all objects, using only common object properties in BaseObject.
目前,我可能想到了三种解决方案:
Currently, I have potentially three solutions in mind:
1) 将对象列表存储在BaseCollection中,如:
1) Store the objects list in BaseCollection, such as:
class BaseCollection {
vector<BaseObject*> objects;
};
这个解决方案的问题是,当我需要在Collection1中执行特定于对象的任务时,我需要一个dynamic_cast<>,因为我不想对特定属性使用虚拟继承,只适用于一种类型的对象.考虑到 dynamic_cast<> 可能每秒被调用数百万次,这对于性能关键型应用程序来说似乎是个问题.
The problem with this solution is that when I need to perform object-specific task in Collection1, I need a dynamic_cast<>, because I don't want to use virtual inherance for specific properties, applying to only one type of object. Considering that dynamic_cast<> could potentially get called millions of time per second, this seems an issue for a performance critical application.
2) 将对象列表存放在Collection1中,如:
2) Store the objects list in Collection1, such as:
class Collection1: public BaseCollection {
vector<Object1*> objects;
}
但是我需要一些方法来访问 BaseCollection 中的这个对象列表,以便能够对它们执行一些常见任务,最好是通过迭代器.我需要创建一个返回 BaseCollection 的向量的函数,但同样,这似乎不是很有效,因为这样做的唯一方法是创建一个新向量(可能包含数千个对象)...
But then I need some way to access this object list in BaseCollection, to be able to perform some common tasks on them, ideally through an iterator. I would need to create a function that return a vector for the BaseCollection, but again, this does not seem very efficient, because the only way to do that is to create a new vector (potentially containing thousands of objects)...
3) 将对象列表存储在 BaseCollection AND Collection1 中:
3) Store the objects list in BaseCollection AND Collection1:
class BaseCollection {
public:
void someCommonTask(); // Use baseObjects
virtual void addObject() = 0;
protected:
vector<BaseObject*> baseObjects;
};
class Collection1: public BaseCollection {
vector<Object1*> objects;
public:
virtual void addObject() {
Object1* obj = new Object1;
objects.push_back(obj);
baseObjects.push_back(obj);
}
void someSpecificTask(); // Use objects, no need of dynamic_cast<>
}
这两个列表实际上包含相同的对象.有那么难看吗?
Where the two lists actually contain the same objects. Is that as ugly as it sounds like?
我正在为此类问题寻找正确/正确/最佳的设计模式,而上面公开的 3 种解决方案中没有一个真正让我满意...
I am looking for the right/correct/best design pattern for this type of problem and none of the 3 solutions exposed above really satisfies me...
也许可以用模板解决这个问题,但是我没有看到像这样存储多态集合列表的方法:
Maybe it is possible to solve that problem with templates, but then I don't see a way to store a list of polymorphic collections like this:
vector<BaseCollection*> collections;
推荐答案
我认为您应该选择选项 1,但改用静态转换.毕竟派生集合肯定知道成员变量的类型.
I think you should go for option 1 but use a static cast instead. After all the derived collection knows the type of the member variable for sure.
这个答案很好地解释了它.
这篇关于正确的设计模式来处理对象的多态集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!