2013-10-21 86 views
0

快速问题。我有一大堆继承类的,像这样:创建继承对象的方法

Object_____ 
    |  | 
Actor Item 
    | 
    |_______ 
Human Animal 

我也已经定义,像这样一个所谓的房间,等级:

class Room 
{ 
    Object * addObject (unsigned long _UID, string _name); 
    map<int, Object *> objects; // A map containing the Objects within the room 
} 

我希望做的是使函数addObject()能够实例化任何类型的对象类,例如Room.addObject(Object::Actor::Human),然后将人类对象添加到房间中的对象列表中。如果有帮助,它们都有相同的构造函数参数。有没有办法在C++中做到这一点?

+2

让我们从“对象”映射只能存储“对象”的实例开始,而不是其任何派生类的实例。 –

+0

“对象”的类型是什么。我怀疑你正在忍受切片。 –

+0

对不起,'objects'应该是'Object *'的映射。 – Sean

回答

1
template<typename T> Object* addObject(...) { 
    Object* myobject = new T(...); 
    objects.insert({someint, myobject}); 
} 

... 
myroom.addObject<Human>(...); 

你需要从存储对象存储对象的指针更改地图,并找出对象的所有者是什么让你清理它们。 (可能有助于使你的地图存储unique_ptr s或shared_ptr s。

+0

我得到一个链接错误:错误错误LNK2019:无法解析的外部符号“public:class Object * __thiscall Room :: addObject (unsigned long,class std :: basic_string , class?std :: allocator >)“(?? $ addObject @ VActor @@@ Room @@ QAEPAVObject @@ KV?$ basic_string @ DU?$ char_traits @ D @ std @@ V?$ allocator @ D @ 2 @@ std @@@ Z)在函数中引用_main \t C:\ Dropbox \ Game Development \ Visual Studio 2012 \ CitySim \ CitySim \ Main.obj – Sean

+0

模板函数实现必须在使用位置可见,所以最好放置它进入标题。 – Slava

+0

@Slava我在头文件中声明了,并在单独的.cpp中定义了我称之为函数的地方。你是说我需要头部中的定义吗? – Sean

1

我认为你在寻找的是C++的工厂模式虽然有许多方法可以用C++实现工厂,但据我所知有没有一个标准的

我想简单的往往是最好的,所以这里使用的示例代码一个非常简单的对象工厂的例子:

#include <memory> 
#include <string> 
#include <map> 
using namespace std; 

// Stub class definitions 
class Object { public: Object() {} ~Object() {} }; 
class Actor : public Object { public: Actor() {} ~Actor() {} }; 
class Human : public Actor { public: Human() {} ~Human() {} }; 
class Animal : public Actor { public: Animal() {} ~Animal() {} }; 
class Item : public Object { public: Item() {} ~Item() {} }; 

class ObjectFactory 
{ 
public: 
    static shared_ptr<Object> create_object(string name); 
}; 

shared_ptr<Object> ObjectFactory::create_object(string name) 
{ 
    if (name == "Human") 
     return shared_ptr<Object>(new Human()); 
    if (name == "Actor") 
     return shared_ptr<Object>(new Actor()); 
    if (name == "Animal") 
     return shared_ptr<Object>(new Animal()); 
    if (name == "Item") 
     return shared_ptr<Object>(new Item()); 
    throw "unknown object type"; 
} 

class Room 
{ 
public: 
    shared_ptr<Object> addObject (unsigned long _UID, string _name); 
    map<int, shared_ptr<Object>> objects; // A map containing the Objects within the room 
}; 

shared_ptr<Object> Room::addObject(unsigned long _UID, string _name) 
{ 
    shared_ptr<Object> object = ObjectFactory::create_object(_name); 
    objects[_UID] = object; // not sure if this is what you intended to use _UID for... 
    return object; 
} 

int main() 
{ 
    Room room; 
    room.addObject(1, "Actor"); 
    return 0; 
} 

注意,这可能在使用Object *完成shared_ptr<Object>的地方,你只是不会有自动引用e计数/删除,并且必须自己跟踪对象(考虑到它们存储在地图中,不太困难)。