我手中有这种情况:
到目前为止,我已经提出了两个解决方案,而且我认为它们都没有错。
解决方案#1:
使用经理+工厂类创建并配对对象A和 B.还将管理对象A的列表/向量。
这个问题是: 1.我需要将经理+工厂对象的实例经常传递给需要实例化对象A和B的任何对象。 2.因为我无法确定将来会有多少对象A和B的变体,我无法进行切换/案例实例化。或者如果我们采用工厂模式的方式,我必须强制要求对象A和B的每个子项都应该有一对工厂类。有点乏味,如果你问我,可能会使应用程序膨胀。 3.它不能强制执行上述规则的第3和第4点。除非我隐藏构造函数并使它们成为私有/受保护,并将经理+工厂类作为朋友类。
解决方案#2:
使对象A自我管理并将其引用存储到静态成员中 创造时的矢量。必须仅通过方法创建对象B. 名为“AddB()”,它将模板类作为输入, 在方法内部,它将实例化模板类并将其存储到向量中 对象B。
这个问题是: 1.我无法确保输入的模板类实际上是对象B的子/派生,因为它毕竟是一个模板。 2.很可能会增加一些性能,因为它毕竟是一个模板。仅供参考,我可能需要经常进行实例化,即使是2000左右。 3.它仍然无法执行上述规则的第3和第4点。除非我隐藏构造函数并使它们成为private / protected,并将A类作为B类的友元类。
那么,关于如何以最好的方式解决这个问题的想法呢?
提前致谢。
答案 0 :(得分:1)
对我来说,它看起来像“因此,对象B不能在对象A之外实例化。”是问题的关键。
模板路由可能是最好的,因为如果类不是向量类型的子类,它会生成编译时错误。我还让每个B(动物)类成为A的朋友,所以A可以使用私有构造函数。它在封装时吃掉了,可能很难维护,但它确实有效。
示例:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Farm;
class Animal {
protected:
Animal() {}
public:
virtual ~Animal() {}
void makeSound() { cout << this->sound() << endl; }
virtual string sound () const = 0;
friend class Farm;
};
class Cat : Animal {
protected:
Cat() {}
public:
virtual ~Cat() {}
virtual string sound () const { return "meow"; }
friend class Farm;
};
class Dog : Animal {
protected:
Dog() {}
public:
virtual ~Dog() {}
virtual string sound () const { return "bark"; }
friend class Farm;
};
class Tractor {
protected:
Tractor() {}
virtual ~Tractor() {}
virtual string sound () const { return "rummm!"; }
friend class Farm;
};
class Farm {
vector< Animal * > animals;
public:
template< typename AnimalType >
void create() {
animals.push_back( new AnimalType );
}
void disturbAnimals() {
for( auto animal : animals ) {
animal->makeSound();
}
}
};
int main( int argc_, char ** argv_ ) {
Farm farm;
farm.create<Cat>();
farm.create<Dog>();
// Generates compile-time error
//farm.create<Tractor>();
farm.disturbAnimals();
return 0;
}