struct Base { ... };
struct A : public Base { ... };
struct B : public Base { ... };
struct C : public Base { ... };
是否有可能創建一個數組,即認爲結構的類型? 樣品/預期的結果:
Type inheritedTypesOfStruct[3] = {A, B, C};
這樣做的目的是,我以後要與來自陣列取回的隨機類創建對象。
struct Base { ... };
struct A : public Base { ... };
struct B : public Base { ... };
struct C : public Base { ... };
是否有可能創建一個數組,即認爲結構的類型? 樣品/預期的結果:
Type inheritedTypesOfStruct[3] = {A, B, C};
這樣做的目的是,我以後要與來自陣列取回的隨機類創建對象。
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <map>
#include <vector>
#include <memory>
using namespace std;
// interface
class Base
{
public:
virtual ~Base() { }
virtual int getClassId() = 0;
};
// class A relizes interface Base, has ID == 1 (is used in automatic registration to factory)
class A : public Base
{
public:
const static int ID = 1;
static Base* CreateInstance()
{
return new A();
}
virtual int getClassId()
{
return ID;
}
virtual ~A() { }
};
// class B relizes interface Base, has ID == 2 (is used in automatic registration to factory)
class B : public Base
{
public:
const static int ID = 2;
static Base* CreateInstance()
{
return new B();
}
virtual int getClassId()
{
return ID;
}
virtual ~B() { }
};
// this is the objects factory, with registration only (unregister s not allowed)
class ObjectFactory
{
ObjectFactory() { }
ObjectFactory(ObjectFactory&) { }
public:
virtual ~ObjectFactory() { }
static ObjectFactory& instance()
{
static ObjectFactory objectFactory;
return objectFactory;
}
typedef Base* (*Creator)();
void registerCreator(int id, Creator creator)
{
registry[id] = creator;
}
Base* CreateById(int id)
{
return registry[id]();
}
private:
map<int, Creator> registry;
};
// this template class is used for automatic registration of object's creators
template <class T>
struct RegisterToFactory
{
RegisterToFactory(ObjectFactory& factory)
{
factory.registerCreator(T::ID, &T::CreateInstance);
}
};
namespace
{
// automaticaly register creators for each class
RegisterToFactory<A> autoregisterACreator(ObjectFactory::instance());
RegisterToFactory<B> autoregisterBCreator(ObjectFactory::instance());
}
// lets this this solution
int main(int argc, char *argv[])
{
vector<int> ids;
ids.push_back(static_cast<int>(A::ID));
ids.push_back(static_cast<int>(B::ID));
srand(time(0));
for (int i = 0; i < 20; ++i)
{
int randomClasssId = ids[rand() % ids.size()];
auto_ptr<Base> testObject(ObjectFactory::instance().CreateById(randomClasssId));
cout << "Object of classId = " << testObject->getClassId() << " has been produced by factory." << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
如果您想保護對象創建者,請將靜態創建者移動到私有/受保護的部分,並將此類朋友帶到具體的外部創建者類。只要創建過程複雜且容易出錯,這可能是有用的。外部創建者完全知道如何正確實例化這個類的對象,所以最終用戶永遠不會在這裏失敗。 – rzur2004 2012-01-02 18:36:35
我不會推薦使用RTTI,除非你知道具體的平臺,並且每個模塊(DLL,SO,LIB ....)都有嚴格的相同的編譯和鏈接選項。當我們嘗試註冊模板類時,一些較早的編譯器可能會遇到與RTTI有關的問題,其中名稱空間和交叉模塊註冊到這樣的工廠尤其如此。通常RTTI是一週,儘量不要使用它,因爲RTTI可能在構建配置時被禁用,並且不會運行。 – rzur2004 2012-01-02 18:45:52
好吧,我嘗試一下,thx – justi 2012-01-02 20:13:23
你可以到這裏看看:http://www.java2s.com/Code/Cpp/Class/Objectarraypolymorphism.htm
如何在C使用多態性++。
問題不是關於多態性,而是鏈接不是答案 – 2012-01-02 16:02:45
我不明白這個問題。你是否要求一個可以同時容納不同類型實例的數組?當然,這可以使用多態。還是你想獲得一個類型數組(如反射)?這可以使用RTTI或Qt類型信息(作爲例子),但我從來沒有這樣做。
要求澄清的內容以評論形式發佈,而不是答案。 – 2012-01-02 16:22:36
您可以創建一個函數數組,每個函數返回一個基指針(或智能指針),每個指針指向各個派生類的對象。例如
typedef std::unique_ptr<Base> base_ptr;
template<typename Derived>
base_ptr CreateObject()
{
return base_ptr(new Derived);
}
int main()
{
std::function<base_ptr(void)> f[3] = {
CreateObject<A>, CreateObject<B>, CreateObject<C>
};
base_ptr arr[10];
for (int i=0; i<10; ++i)
arr[i] = f[rand()%3]();
}
這是在行動:http://ideone.com/dg4uq
你的意思是這樣的:'向量 V;' –
2012-01-02 15:44:11
你想要的類型本身的數組?或者這些類型的對象數組? – 2012-01-02 15:46:38
@ BenjaminLindley:顯然他想要一個類型的數組。然而,使用'Base'作爲數組項目類型是有誤導性的。 – 2012-01-02 15:47:34