1

我有一个抽象基类,称为Base其他程序员要为其编写实现。在应用程序的其他部分,我想捕获所有已编写的实现并构造每个实现的单个实例。如果除了“实施基础”之外,无需向其他人提供额外的指示,这将是美好的。但是,我在下面的代码要求每个实现都注册自己。它也不起作用。

#include <iostream>
#include <vector>

class Base;

std::vector<Base*>* registrationList = new std::vector<Base*>;

class Base {
public:
   Base(){}
   virtual void execute() = 0;
};

class ImplementationOne: public Base {
public:
   ImplementationOne(){registrationList->push_back(this);}
   void execute(){std::cout << "Implementation One." << std::endl;}
   static int ID;
};

class ImplementationTwo: public Base {
public:
   ImplementationTwo(){registrationList->push_back(this);}
   void execute(){std::cout << "Implementation Two." << std::endl;}
   static int ID;
};

int main(int argc, const char * argv[]){
   std::cout << "Registration List size: " << registrationList->size() << std::endl;
   for(auto it = registrationList->begin() ; it != registrationList->end() ; ++it){
      (dynamic_cast<Base*>(*it))->execute();
   }
   return 0;
}

我得到一个输出: Registration List size: 0,所以很明显这些实现从来没有被实例化过。很明显这不会发生,但我是一个初学者,这是我能想到的最好的。我假设这static int ID;将强制实例化每个实现,然后将它们自己注册。我可以看到static不会导致实例化。我将它留在我的代码中,因为它显示了我的意图。

我该怎么做才能自动实例化每个实现?可能吗?

4

2 回答 2

1

添加static成员不会导致生成实例,它只是声明此类型具有“全局”变量。但是,您从未真正定义过这些成员,因此如果您尝试将它们用于任何事情,您将遇到链接器错误。您必须实际实例化一个对象并注册它。

一种解决方案可能是简单地要求每个派生类型在启动时注册一个实例。正如我在这里展示的那样,这实际上很容易完成。(请注意,我将您的全局移动到静态函数的静态局部。这可以防止您尚未遇到的几个问题,包括为全局提供“所有者”。)


与您的问题无关,您的代码有问题:

  • 几乎没有任何理由拥有指向容器的指针。
  • 您从没有虚拟析构函数的类型中以多态方式派生。
  • dynamic_cast<Base*>没有明显的原因。
  • 您的每个派生类都声明但不定义成员ID
于 2013-07-01T18:41:08.203 回答
0

当然向量是空的,你永远不会向它添加任何东西。派生类的构造函数不会被调用,因为您从未创建它们的任何对象实例。

仅仅因为您拥有静态成员并不意味着将创建任何对象实例。它只是保证不同实例之间的值相同。

您必须显式创建类的实例才能调用构造函数。

于 2013-07-01T18:15:39.700 回答