1

First of all, I have been looking on stackoverflow for more than 1 hour, but I really don't know, how to find the specific question I'm looking for (I guess there is already some answer). I am trying to call an object via variable (string) example of my code:

//class itself 
using namespace std   
class locations {
public:
    locations(int id, string name){  // constructor
        this->id= id;
        this->name=name;
    }
    int id= 0;
    string name = "";
};

and new object:

locations home(1,"home");

what I want now is something like:

string obj = "home";
obj.id = 3;

or

string meth = "id";
home.meth = 3;

If you have any good links to other questions it would be helpful. Maybe it can be accessed somehow through vectors but I don't know about it a lot

Razib
  • 10,965
  • 11
  • 53
  • 80
Kuba Šimonovský
  • 2,013
  • 2
  • 17
  • 35
  • 2
    No, C++ isn't Actionscript. Without well-defined semantics for your location class it's hard to say what the solution is. Try looking into `std::vector` or `std::map`. –  Mar 21 '15 at 14:03
  • 1
    "call an object via variable (string)" – means what? – The Paramagnetic Croissant Mar 21 '15 at 14:24
  • well, if you can't understand this question, try to understand example – Kuba Šimonovský Mar 21 '15 at 14:27
  • You might want to look at [pointer to class data members](http://stackoverflow.com/questions/670734/) or [pointer to class method](http://stackoverflow.com/questions/1485983/) as a slightly related topic. It's sort of like "access by name" except strongly typed for just that member of instances of that class. You'd probably be going down the road of "what you don't actually want" if you read up on things like the [Qt Meta Object Protocol](http://doc.qt.io/qt-5/topics-core.html) vs. taking the advice of working with something like a std::map for naming things...but it may be interesting anyway. – HostileFork says dont trust SE Mar 21 '15 at 15:00
  • 1
    The first example doesn't really make sense. You define `string obj` and then try to assign 3 to a member `id` of string. What should that do? string and location are two different things, that is why they are different types. The second case probably should call method id with parameter 3, but what you write is an assignment of the value three to the member meth in a location object. Since there is no such field, it fails to compile. – Jens Mar 21 '15 at 15:08
  • 1
    I think you want to call a member function dynamically based on a name in a string. This is not possible in C++. C++ does not have reflection or introspection and is statically typed.You could implement your own object system based on maps and std::functions, but then I would use another language. – Jens Mar 21 '15 at 15:09

2 Answers2

1

C++ is designed with strong typing and compile time checking and optimization in mind. There's no build in facilities for the kind of access that you desire.

1) Find dynamically an object:

C++ doesn't support the semantic that you expect:

 string obj = "home";  // create an object of type string.  
 obj.id = 3;           // access to member id of your object.

If it would be dynamic, the generated code would need to maintain the scope of variables (because the home object can have different meansings in different scope.

But fortunately you can easily implement an object store, in wich you register your objects and their name, with the help of a map :

map<string, locations> mystore;    // store of all my location variables 
mystore["home"] = locations(1,"home");   // copy a new object into the store

string obj = "home";
mystore[obj].id = 3;   // access object via its name.  

By the way, if locations::name is only there to give access by name, you'd no longer need it in locations, as the map links the string to the object value anyway.

2) Find dynamically a member:

C++ doesn't support your semantic at all:

string meth = "id";  // name of a member 
home.meth = 3;       // invalid:  because meth is not a member of home

C++ doesn't support reflection that you find in java and other semi-compiled or interpreted languages. If you need something like that, you'd need to design carefully your classes to implement this by yourself. It'll be rather difficult as every member can have its own type, and C++ needs to know the type at compile time.

One way would be to combine the use of a map (to store your dynamic members) with the use of boost::variant (to store in the map objects that can have different type of values).

But it's not easy, and most of all, you'd have to manage by yourself any inheritance logic betwwen diferent classes.

Community
  • 1
  • 1
Christophe
  • 68,716
  • 7
  • 72
  • 138
  • To the second point, one can build an `[unordered_]map memberMap` and call `(obj->*memberMap[name])();`… also one can use lambdas (stored as `std::function`s) as well if the parameter types don't match. – The Paramagnetic Croissant Mar 21 '15 at 17:42
1

This isn't how thing are done in C++, C++ is a object oriented, statically typed, value semantics language. All of these affect design, and the design you seem want just don't fit with a statically typed language. Whether this lead you to change design, or change language is up to you. That said, if you really want to map objects and methods runtime, it could be emulated something like this:

#include <iostream>
#include <string>
#include <map>

using namespace std;

struct Object;

typedef int (*funcptr)(Object*,int);

struct Object
{
  map<string,funcptr> funcs;
  map<string,int> data;
  int call(string name,int param) { return funcs[name](this,param); }
};

map<string,Object> allObjects;

Object& get(string name) { return allObjects[name]; }

//----------------------------------------------------------------------------------

int main()
{

  get("obj1").funcs["run"] = [](Object* self,int param) -> int { self->data["somename"] = param; return 0; };

  get("obj1").call("run",5);

  cout << get("obj1").data["somename"] << endl;
}

That said, please don't do that, change your design to something that actually is a good fit for C++'s strengths, i.e. object oriented, statically typed, value semantics.