简体   繁体   中英

Creating an Object Based on a Function Arguement C++

Say I have a member function that creates a new object and places it into a data structure (in this case a map) in the class:

Class A
{
    std::map<std::pair<int,int>, BaseClass*> store;
    //...
    public:
    void createObject(?a?)
    {
        BaseClass* temp = new ?a?;
        //place in map...
    };
};

Where ?a? is an argument that can be used to create an object that can be a number of different classes derived from BaseClass . The only way I can think of doing this is by making ?a? an int , and manually typing each type into a switch statement.

Use a member function template. In the context of your example:

template<class T>
void createObject()
{
    BaseClass* temp = new T();
    //place in map...
};

Invoke with:

a.createObject<B>();

Where a is an instance of A , and B is a type derived from BaseClass .

A template is a better solution than an enum because it doesn't require any maintenance. Any new subclasses will automatically be supported. Type safety between pointer types guarantees that T is a subclass of temp (otherwise the assignment will fail).

Class A
{
    std::map<std::pair<int,int>, BaseClass*> store;
    //...
    public:
    template <typename T>
    void createObject()
    {
        BaseClass* temp = new T();
        //place in map...
    };
};

The compiler cannot deduce the template type automagically without a dependant argument, so you'll need to qualify it.

Class Foo : public BaseClass { ... };

A a;
a.createObject<Foo>();

Depends how you know what kind of object to create.

If it is reasonable to base that on an int (eg a return code from some function) then a switch statement is fine. Note that you need to create each object with a call to new for it's type and then cast the object pointer to BaseClass to put into the map.

If you are passing in an object of the type then use a template. edit: as Jon's answer

You should make an enumeration of the possible classes that can be created and pass one to createObject function, for example:

enum FRUIT_CLASS { APPLE, ORANGE, BANANA };
...
void A::createObject( FRUIT_CLASS )
{ 
  switch(FRUIT_CLASS)
  // etc
}

This way, you are actually passing an integer as a parameter, but your code is more understandable, modifiable and maintainable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM