如何在C++中强制在另一个对象(依赖于它)中实例化一个对象

How to enforce instantiating an object in another object (that depends on it) in C++

本文关键字:一个对象 依赖于 实例化 C++      更新时间:2023-10-16

我已经掌握了这种情况:

  1. 对象A依赖于一个或多个对象B(及其子对象)
  2. 对象A和B可以有多个实例。它们应该插入某个列表中(B对象的列表以向量的形式存在于拥有它们的对象A中)
  3. 对象B(及其后代)不能生活在另一个对象内部,也不能生活在一个特定于对象a的唯一对象中
  4. 因此,对象B不能在对象A之外实例化
  5. 如果对象A已经实例化,它可以动态创建对象B(及其子体)的实例,并将其推送到对象B的向量中
  6. 对象A和对象B都可以无限地衍生为许多变体

到目前为止,我已经提出了两个解决方案,我不认为它们都有问题。

解决方案#1:

使用管理器+工厂类,该类将创建对象a和B.它还将管理对象A的列表/矢量。

这个问题是:1.我需要将管理器+工厂对象的实例传递给任何需要实例化对象a和B的对象。2.因为我无法确定未来会派生出多少对象A和B的变体,所以我无法进行开关/事例实例化。或者,如果我们采用工厂模式,我必须强制对象A和B的每个子对象都应该为自己拥有一个配对工厂类。有点乏味,如果你问我的话,可能会让应用程序膨胀。3.不能执行上述规则的第3点和第4点。除非我隐藏构造函数并将它们设为私有/受保护的,并将manager+factory类设为友元类。

解决方案2:

使对象A管理自己,并将其引用存储到静态成员中创造时的矢量。对象B只能通过方法创建名为"AddB()",它将有一个模板类作为输入,在方法内部,它将实例化模板类并将其存储到向量中对象B.

这个问题是:1.我真的不能确定输入的模板类实际上是对象B的子类/派生类,因为它毕竟是一个模板。2.很可能会增加一些性能,因为它毕竟是一个模板。仅供参考,我可能需要经常实例化它,甚至一次实例化2000 ish左右。3.仍然无法执行上述规则的第3点和第4点。除非我隐藏构造函数,使它们成为私有/受保护的,并使A类成为B类的朋友类。

那么,你知道如何以最好的方式解决这个问题吗?

提前谢谢。

对我来说,问题的关键是"因此,对象B不能在对象A之外实例化。"。

模板路由可能是最好的,因为如果类不是向量类型的子类,它会生成编译时错误。我还让每个B(Animal)类都是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;
}
相关文章: