0

How to define variable according to string. I had defined many classes.But I want to creat variable of this class according to some string.

The code looks like this.

class AA {};
class BB {};
class CC {
    CC(void *pt);
    virtual ~CC();
};
......

void test(char *ss,void *pt=NULL) {
    //??????How to do?

}

int main() {
    a1=test("AA");    //a1=new AA();
    a2=test("AA");    //a2=new AA();
    b1=test("BB");    //b1=new BB();
    c1=test("CC",pt); //c1=new CC(pt);
}

Orther,you can consider this as URL and handle function.The std::map is common method to get instance of class according to string.But can't create a new instance to variable. I hope get a new instance according to string.

simon
  • 569
  • 9
  • 20

3 Answers3

5

C++ is a strongly typed language, so this isn't possible as you have it now.

Best case, you'd use a common base class for AA, BB, CC and then use a factory. You can't just write:

a1=test("AA");    //a1=new AA();
a2=test("AA");    //a2=new AA();
b1=test("BB");    //b2=new BB();
c1=test("CC",pt); //b2=new CC(pt);

without defining a type for the variables.

For example:

class Base{};
class AA : public Base {};
class BB : public Base {};

Base* create(const std::string& what)
{
   if (what == "AA")
       return new AA;
   if (what == "BB")
       return new BB;
   return NULL;
}

int main()
{
    Base* a;
    a = create("AA");
}

Alternitively, you should use smart pointers. If you don't you'll have to manage the memory yourself.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • This class like AA,BB can't know.I hope encapsulation the function of "create" .Order people will make class like AA,BB.I only write base class and create function. – simon Sep 24 '12 at 11:52
  • Maybe,this class will write more like "CC","DD","EE"......I don't want modify the function of "create" . – simon Sep 24 '12 at 11:59
  • @user1641913 then you'll need a map of callbacks to functions that create a specific class and extend that map when you add a new class. – Luchian Grigore Sep 24 '12 at 12:04
  • std::map don't help define variable....This is common method to get instance of class according to string...But can't create a new instance to variable. – simon Sep 24 '12 at 12:15
  • @user1641913 do you know what a callback is? I said you should have a map of strings to callbacks - i.e. functions that generate instances of the class. – Luchian Grigore Sep 24 '12 at 12:16
  • Sorry.I have write a wrong positon,I copy it.This is a answer to Dietmar Kühl.I am thinking the method. – simon Sep 24 '12 at 12:30
  • This means that users to use the project have to write the function..May be the callback function may be factory functions。Perhaps the only way! – simon Sep 24 '12 at 13:02
1

You probably want you function to return something, either void* or, preferably, a [smart] pointer to a common base. The string should probably be passed as char const* or as std::string const&. Within the function you either directly compare the argument and you call the appropriate allocation or you create a std::map<std::string, FactoryFunction> to look up a factory function based on the string.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • std::map don't help define variable....This is common method to get instance of class according to string...But can't create a new instance to variable. – simon Sep 24 '12 at 12:11
  • Read my answer again: the map would hold a mapping from string to factory function. You'd call the found function to create your instance (assuming one is found; if none is found you'signal an error, e.g., by throwing an exception). – Dietmar Kühl Sep 24 '12 at 12:17
  • You are right.But I have to write function for each class.Perhaps the only way! – simon Sep 24 '12 at 13:06
  • You need to write two functions: one for the flavor passing the pointer and one for the others: `template T* createSimple(void*) { return new T(); }` and similarly a version using the argument. You can then register it using `&createSimple`. – Dietmar Kühl Sep 24 '12 at 13:50
0

Maybe instead of using string names of types - use types as they are. To do this - use templates.

class AA {};
class BB {};
class CC {
public:
    CC(void *pt) {}
    virtual ~CC() {}
};

template <class T>    
T* test() {
    return new T();

}
template <class T>    
T* test(void *pt) {
    return new T(pt);

}

int main() {
    void* pt;
    AA* a1=test<AA>();    //a1=new AA();
    AA* a2=test<AA>();    //a2=new AA();
    BB* b1=test<BB>();    //b1=new BB();
    CC* c1=test<CC>(pt); //c1=new CC(pt);
}
PiotrNycz
  • 23,099
  • 7
  • 66
  • 112