代码:
struct Base { ... };
struct A : public Base { ... };
struct B : public Base { ... };
struct C : public Base { ... };
是否可以创建一个包含这种类型结构的数组? 样本/预期结果:
Type inheritedTypesOfStruct[3] = {A, B, C};
这样做的目的是我后来想要创建一个带有从数组中检索的随机类的对象。
答案 0 :(得分:5)
如果您的编译器支持RTTI,您可以执行以下操作:
const type_info *inheritedTypesOfStruct[3] = {
&typeid(A), &typeid(B), &typeid(C)
};
但是,您将无法仅使用其type_info实例化一个类。 factory pattern可能是您根本问题的更好解决方案。
更新:由于type_info
实例无法复制(其复制构造函数和赋值运算符为private
),并且引用数组是非法的,因此必须使用常量指针在上面的例子中。
答案 1 :(得分:5)
您可以创建一个函数数组,每个函数都返回一个基指针(或智能指针),每个指针都指向各种派生类的对象。 e.g。
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]();
}
答案 2 :(得分:1)
#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;
}
答案 3 :(得分:0)
我不明白这个问题。你是否要求一个可以同时容纳不同类型实例的数组?当然,使用多态可能是可能的。或者您是否想要获得一系列类型(如反射)?这可以使用RTTI或Qt类型信息(作为示例),但我从未这样做过。
答案 4 :(得分:-1)
您可以在此处查看:http://www.java2s.com/Code/Cpp/Class/Objectarraypolymorphism.htm
关于如何在C ++中使用多态性。