C++ dynamic class ( dynamic hack ) - c++

Is there any way to add a field to a class at runtime ( a field that didn't exist before ) ? Something like this snippet :
Myobject *ob; // create an object
ob->addField("newField",44); // we add the field to the class and we assign an initial value to it
printf("%d",ob->newField); // now we can access that field
I don't really care how it would be done , I don't care if it's an ugly hack or not , I would like to know if it could be done , and a small example , if possible .
Another Example: say I have an XML file describing this class :
<class name="MyClass">
<member name="field1" />
<member name="field2" />
</class>
and I want to "add" the fields "field1" and "field2" to the class (assuming the class already exists) . Let's say this is the code for the class :
class MyClass {
};
I don't want to create a class at runtime , I just want to add members/fields to an existing one .
Thank you !

Use a map and a variant.
For example, using boost::variant. See http://www.boost.org/doc/libs/1_36_0/doc/html/variant.html
(But of course, you can create your own, to suit the types of your XML attributes.)
#include <map>
#include <boost/variant.hpp>
typedef boost::variant< int, std::string > MyValue ;
typedef std::map<std::string, MyValue> MyValueMap ;
By adding MyValueMap as a member of your class, you can add properties according to their names. Which means the code:
oMyValueMap.insert(std::make_pair("newField", 44)) ;
oMyValueMap.insert(std::make_pair("newField2", "Hello World")) ;
std::cout << oMyValueMap["newField"] ;
std::cout << oMyValueMap["newField2"] ;
By encapsulating it in a MyObject class, and adding the right overloaded accessors in this MyObject class, the code above becomes somewhat clearer:
oMyObject.addField("newField", 44) ;
oMyObject.addField("newField2", "Hello World") ;
std::cout << oMyObject["newField"] ;
std::cout << oMyObject["newField2"] ;
But you lose somewhat the type safety of C++ doing so. But for XML, this is unavoidable, I guess.

There's no way to do it in the way you've described, since the compiler needs to resolve the reference at compile time - it will generate an error.
But see The Universal Design Pattern.

You can't make that syntax work (because of static checking at compile time), but if you're willing to modify the syntax, you can achieve the same effect pretty easily. It would be fairly easy to have a dictionary member with a string->blob mapping, and have member functions like:
template< typename T > T get_member( string name );
template< typename T > void set_member( string name, T value );
You could make the syntax more compact/tricky if you want (eg: using a '->' operator override). There are also some compiler-specific tricks you could possibly leverage (MSVC supports __declspec(property), for example, which allows you to map references to a member variable to methods of a specific format). At the end of the day, though, you're not going to be able to do something the compiler doesn't accept in the language and get it to compile.

Short version: Can't do it. There is no native support for this, c++ is statically typed and the compiler has to know the structure of each object to be manipulated.
Recommendation: Use an embedded interperter. And don't write your own (see below), get one that is already working and debugged.
What you can do: Implement just enough interperter for your needs.
It would be simple enough to setup the class with a data member like
std::vector<void*> extra_data;
to which you could attach arbitrary data at run-time. The cost of this is that you will have to manage that data by hand with methods like:
size_t add_data_link(void *p); // points to existing data, returns index
size_t add_data_copy(void *p, size_t s) // copies data (dispose at
// destruction time!), returns
// index
void* get_data(size_t i); //...
But that is not the limit, with a little more care, you could associate the arbitrary data with a name and you can continue to elaborate this scheme as far as you wish (add type info, etc...), but what this comes down to is implementing an interperter to take care of your run-time flexibility.

No -- C++ does not support any manipulation of the type system like this. Even languages with some degree of runtime reflection (e.g. .NET) would not support exactly this paradigm. You would need a much more dynamic language to be able to do it.

I was looking at this and I did a little search around, this code snippet obtained from : Michael Hammer's Blog
seems to be a good way to do this, by using boost::any
First you define a structure that defines an std::map that contains a key (i.e. variable name) and the value. A function is defined to ad the pair and set it along with a function to get the value. Pretty simple if you ask me, but it seems a good way to start before doing more complex things.
struct AnyMap {
void addAnyPair( const std::string& key , boost::any& value );
template<typename T>
T& get( const std::string key ) {
return( boost::any_cast<T&>(map_[key]) );
}
std::map<const std::string, boost::any> map_;
};
void AnyMap::addAnyPair( const std::string& key , boost::any& value ) {
map_.insert( std::make_pair( key, value ) );
}
Bottom line, this is a hack, since C++ is strict type-checking language, and thus monster lie within for those that bend the rules.

Related

Mapping data members of a class

I am trying to design a data stuctures, which would enhance/supplement an existing one by storing some additional data about it's members.
Let's say we have:
class A {
int x;
string y;
};
And we want to have a GUI component associated with it, so the data members have corresponding GUI elements. I'd like to map the members to their respective components. Something like
class GuiA {
int x;
string y;
map<MemberHandle, GuiElement*> guiHandles;
}
I don't have any restrictions, but I'd like the result to be easily convertible to the original type.
I am aware, that I could introduce a template e.g. GuiElementMember holding original data plus the GuiElement pointer, and swap class member for their decorated counterparts, so it would look like:
class GuiA {
GuiElementMember<int> x;
GuiElementMember<string> y;
}
but I'd like to avoid it, as it completely changes access patterns to data members and bloats it. I.e. it results with data members interleaved with pointers, that are not easy to strip out.
Ideally it would be possible to write GuiA as a derived class of A, or as a composition of A and something additional.
I was thinking about something like a template that class could produce the map. I could yield to write a custom class per component, but I don't think there is an easy way to map data members, so on the clients side it would look like getGuiMember(GuiA::x). The pointer to data member contains the member original type. I don't think it is possible to have something like "type-erased pointer to member" that could serve as a MemberHandle type.
The only thing that comes to my mind is a custom enum per component which would enumerate data members and serve as key type for a map (or a vector in this case), but it seems as an awful lot of information duplication and maintenance.
Is there some technique that allows mapping data members?
I don't really care about the implementational complexity as long as the interface is easy. I welcome boost or template magic. I also don't care about the performance of additional data access, it's extra stuff, but the plain class usage should not be impacted, so introduction of indirection that cannot be optimized is less welcomed.
EDIT: Please don't hinge on GUI thing it's an example. I am only concerned about storing some additional data per member without composing it with the member.
You can use BOOST_FUSION_DEFINE_STRUCT to define your structures that can be iterated over with a for_each loop:
#include <boost/fusion/include/define_struct.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <unordered_map>
#include <string>
#include <cstdint>
BOOST_FUSION_DEFINE_STRUCT(
(demo), employee,
(std::string, name)
(int, age)
)
struct GuiElement;
GuiElement* createGuiElement(char const* name);
using Mapping = std::unordered_map<size_t, GuiElement*>;
template<class T>
Mapping create_mapping(T&& t) {
Mapping mapping;
boost::fusion::for_each(t, [&](auto& member) {
auto offset = reinterpret_cast<uintptr_t>(&member) - reinterpret_cast<uintptr_t>(&t);
mapping[offset];
});
return mapping;
}
template<class T, class M>
GuiElement*& get_mapping_element(Mapping& mapping, T const& t, M const& member) {
auto offset = reinterpret_cast<uintptr_t>(&member) - reinterpret_cast<uintptr_t>(&t);
auto found = mapping.find(offset);
if(found == mapping.end())
std::abort();
return found->second;
}
int main() {
auto employee_mapping = create_mapping(demo::employee{});
demo::employee e1;
get_mapping_element(employee_mapping, e1, e1.name) = createGuiElement("name");
get_mapping_element(employee_mapping, e1, e1.age) = createGuiElement("age");
}
In the code there is a Mapping, one per class. Each member is identified by its offset from the beginning of its enclosing class.
In general, you use macros for such purposes. They can generate any kind of code/wrappers that you'd like, letting you have the usual access to your data, but also adding stuff you want/need. It ain't pretty, but it works.
There are some template libraries that can help here, like Boost.Fusion or Boost.Hana, but, you can also roll your own here if you don't have a use for their advanced features (which come with the long compilation price tag).
Also, if you can focus on a particular GUI framework, they have some support for such things. For example, Qt has its own "meta object" compiler.
You could try a template for this?
e.g.
template <typename T>
class GuiItem : public T {
map<MemberHandle, GuiElement*> guiHandles;
}
GuiItem<A> guiA;
guiA.x = 123;
guiA.y = "y";
guiA.guiHandles[handle] = element;
I'm not sure I understand the other requirements so this way may not work for you.

Adding data into map using type alias, alias template

I am new to C++. I am not able to understand this code snippet's logic. Could some help me understand this and help me with the concept loading data into the map using the function defined. Problem Explanation : Param1 refers to variables A and B and Param2 refers to B and C.
class VariableInformation
{
using ParameterNameSet = std::set<std::string>;
using VariableReferences = std::map<std::string, ParameterNameSet>;
VariableReferences m_referencesToVariables;
public:
void addReferenceToVariable(std::string parameterName, std::string variableName)
{
m_referencesToVariables[variableName].insert(parameterName);
}
};
what you are looking at is the new c++11 way of doing typedef. so, a statement like:
using ParameterNameSet = std::set<std::string>;
is equivalent to this:
typedef std::set<std::string> ParameterNameSet;
i know a lot of engineers prefer the new syntax. personally, i am old school. i like the typedef way. to each, their own.
as for what the code does, it defines a map of sets:
VariableReferences m_referencesToVariables;
it then uses the overloaded std::map::operator [] to either access an existing element, or insert one if not there (together with an empty set). the std::map::operator [] returns a reference to it's value (the set) which is then used to insert into. hope this helps.

C++: Using a string parameter passed in to access something in a type

My goal is to access a class that is passed in as a parameter inside of myFunction.
Here's what I'm trying to do:
void myFunction(string myString)
{
callFunctionOn(OuterType::InnerType::myString);
}
I'm trying to call some function on something that's in a type. For example, my code in some other file might look like:
namespace OuterType {
namespace InnerType {
//stuff here
}
}
However, using myString in that way doesn't work. If myString holds the value "class1", then I want that callFunctionOn part to be interpreted as
callFunctionOn(OuterType::InnerType::class1);
I feel like this is super simple, but I've been programming all day and my mind grows tired...
SOLVED: It looks like in order to this in this way, I'd need a language with reflection. To solve this I took a different approach to the problem and passed in a pointer to the class instead.
C++ doesn't have reflection built in, but it does have pointers to data, functions, and class members. So you can use a std::map or unordered_set to find the pointer with a particular name (you have to add all the name/pointer pairs into the map beforehand).
Your solution is likely to look something like:
namespace Outer
{
namespace Inner
{
void funcA( void ) { std::cout << "called funcA" << std::endl; }
std::map< std::string, void (*)(void) > members;
}
}
// in some initialization function
Outer::Inner::members["funcA"] = &Outer::Inner::funcA;
// later
std::string myString = "funcA";
void (*f)(void) = Outer::Inner::members[myString]; // lookup function by name
(*f)(); // call function via its pointer
Of course the type of the pointer will probably need to change to meet your application requirements.
You're trying to access a variable based on a run-time string that contains its name? That's not possible; the names of variables disappear after compilation and linking. (Except insofar as they are kept around to facilitate debugging).
Do you mean :
OuterType::InnerType::callFunctionOn(myString);
maybe this idea: operator() can take parameters, wrapping it in a class ine can make calls that are resolved in the overloaded operator() based on its parameters.
template<typename TypeSig, class InstanceOf, typename NA,typename Args>
class FuncMap {
public:
typedef TypeSig (InstanceOf:: *cbMethod) ( NA, Args );
FuncMap( InstanceOf & cInst, cbMethod cbM ) : mcInst(cInst) {mcbM = cbM;}
TypeSig operator() ( NA na, Args args) {return (mcInst.*mcbM)(na, args);}
private:
InstanceOf & mcInst;
cbMethod mcbM;
};
you need to build a map of runtime string values as keys and pointers to instance methods as seen above. i used this for re-dispatch tracing and custom runtime dispatch with lesser than RTTI overhead.
this allows you to have default, if no key found, or other logic as you wish.

Is there a way to apply an action to N C++ class members in a loop over member names (probably via pre-processor)?

The problem:
I have a C++ class with gajillion (>100) members that behave nearly identically:
same type
in a function, each member has the same exact code done to it as other members, e.g. assignment from a map in a constructor where map key is same as member key
This identicality of behavior is repeated across many-many functions (>20), of course the behavior in each function is different so there's no way to factor things out.
The list of members is very fluid, with constant additions and sometimes deletions, some (but not all) driven by changing columns in a DB table.
As you can imagine, this presents a big pain-in-the-behind as far as code creation and maintenance, since to add a new member you have to add code to every function
where analogous members are used.
Example of a solution I'd like
Actual C++ code I need (say, in constructor):
MyClass::MyClass(SomeMap & map) { // construct an object from a map
intMember1 = map["intMember1"];
intMember2 = map["intMember2"];
... // Up to
intMemberN = map["intMemberN"];
}
C++ code I want to be able to write:
MyClass::MyClass(SomeMap & map) { // construct an object from a map
#FOR_EACH_WORD Label ("intMember1", "intMember2", ... "intMemberN")
$Label = map["$Label"];
#END_FOR_EACH_WORD
}
Requirements
The solution must be compatible with GCC (with Nmake as make system, if that matters).
Don't care about other compilers.
The solution can be on a pre-processor level, or something compilable. I'm fine with either one; but so far, all of my research pointed me to the conclusion that the latter is just plain out impossible in C++ (I so miss Perl now that I'm forced to do C++ !)
The solution must be to at least some extent "industry standard" (e.g. Boost is great, but a custom Perl script that Joe-Quick-Fingers created once and posted on his blog is not. Heck, I can easily write that Perl script, being much more of a Perl expert than a C++ one - I just can't get bigwigs in Software Engineering at my BigCompany to buy into using it :) )
The solution should allow me to declare a list of IDs (ideally, in only one header file instead of in every "#FOR_EACH_WORD" directive as I did in the example above)
The solution must not be limited to "create an object from a DB table" constructor. There are many functions, most of them not constructors, that need this.
A solution of "Make them all values in a single vector, and then run a 'for' loop across the vector" is an obvious one, and can not be used - the code's in a library used by many apps, the members are public, and re-writing those apps to use vector members instead of named members is out of the question, sadly.
Boost includes a great preprocessor library that you can use to generate such code:
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/cat.hpp>
typedef std::map<std::string, int> SomeMap;
class MyClass
{
public:
int intMember1, intMember2, intMember3;
MyClass(SomeMap & map)
{
#define ASSIGN(z,n,_) BOOST_PP_CAT(intMember, n) = map[ BOOST_PP_STRINGIZE(BOOST_PP_CAT(intMember, n))];
BOOST_PP_REPEAT_FROM_TO(1, 4, ASSIGN, nil)
}
};
Boost.Preprocessor proposes many convenient macros to perform such operations. Bojan Resnik already provided a solution using this library, but it assumes that every member name is constructed the same way.
Since you explicitely required the possibily to declare a list of IDs, here is a solution that should better fulfill your needs.
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/stringize.hpp>
// sequence of member names (can be declared in a separate header file)
#define MEMBERS (foo)(bar)
// macro for the map example
#define GET_FROM_MAP(r, map, member) member = map[BOOST_PP_STRINGIZE(member)];
BOOST_PP_SEQ_FOR_EACH(GET_FROM_MAP, mymap, MEMBERS)
// generates
// foo = mymap["foo"]; bar = mymap["bar];
-------
//Somewhere else, we need to print all the values on the standard output:
#define PRINT(r, ostream, member) ostream << member << std::endl;
BOOST_PP_SEQ_FOR_EACH(PRINT, std::cout, MEMBERS)
As you can see, you just need to write a macro representing the pattern you want to repeat, and pass it to the BOOST_PP_SEQ_FOR_EACH macro.
You could do something like this: create an adapter class or modify the existing class to have a vector of pointers to those fields, add the addresses of all member variables in question to that vector in the class constructor, then when needed run the for-loop on that vector. This way you don't (or almost don't) change the class for external users and have a nice for-loop capability.
Of course, the obvious question is: Why do you have a class with 100 members? It doesn't really seem sane.
Assuming it is sane nevertheless -- have you looked at boost preprocessor library? I have never used it myself (as one friend used to say: doing so leads to the dark side), but from what I heard it should be the tool for the job.
Surreptitiously use perl on your own machine to create the constructor. Then ask to increase your salary since you're succesfully maintaining such a huge chunk of code.
You could use the preprocessor to define the members, and later use the same definition to access them:
#define MEMBERS\
MEMBER( int, value )\
SEP MEMBER( double, value2 )\
SEP MEMBER( std::string, value3 )\
struct FluctuatingMembers {
#define SEP ;
#define MEMBER( type, name ) type name
MEMBERS
#undef MEMBER
#undef SEP
};
.. client code:
FluctuatingMembers f = { 1,2., "valuesofstringtype" };
std::cout <<
#define SEP <<
#define MEMBER( type, name ) #name << ":" << f.##name
MEMBERS;
#undef MEMBER
#undef SEP
It worked for me, but is hard to debug.
You can also implement a visitor pattern based on pointer-to-members. After the preprocessor solution, this one turns out way more debuggeable.
struct FluctuatingMembers {
int v1;
double v2;
std::string v3;
template<typename Visitor> static void each_member( Visitor& v );
};
template<typename Visitor> void FluctuatingMembers::each_member( Visitor& v ) {
v.accept( &FluctuatingMembers::v1 );
v.accept( &FluctuatingMembers::v2 );
v.accept( &FluctuatingMembers::v3 );
}
struct Printer {
FluctuatingMembers& f;
template< typename pt_member > void accept( pt_member m ) const {
std::cout << (f::*m) << "\n";
}
};
// you can even use this approach for visiting
// multiple objects simultaneously
struct MemberComparer {
FluctuatingMembers& f1, &f2;
bool different;
MemberComparer( FluctuatingMembers& f1, FluctuatingMembers& f2 )
: f1(f1),f2(f2)
,different(false)
{}
template< typename pt_member > void accept( pt_member m ) {
if( (f1::*m) != (f2::*m) ) different = true;
}
};
... client code:
FluctuatingMembers object1 = { 1, 2.2, "value2" }
, object2 = { 1, 2.2, "valuetoo" };
Comparer compare( object1, object2 );
FluctuatingMembers::each_member( compare );
Printer pr = { object1 };
FluctuatingMembers::each_member( pr );
Why not do it at run time? (I really hate macro hackery)
What you really are asking for, in some sense, is class metadata.
So I would try something like:
class AMember{
......
};
class YourClass{
AMember member1;
AMember member2;
....
AMember memberN;
typedef AMember YourClass::* pMember_t;
struct MetaData : public std::vector<std::pair<std::string,pMember_t>>{
MetaData(){
push_back(std::make_pair(std::string("member1"),&YourClass::member1));
...
push_back(std::make_pair(std::string("memberN"),&YourClass::memberN));
}
};
static const MetaData& myMetaData() {
static const MetaData m;//initialized once
return m;
}
YourClass(const std::map<std::string,AMember>& m){
const MetaData& md = myMetaData();
for(MetaData::const_iterator i = md.begin();i!= md.end();++i){
this->*(i->second) = m[i->first];
}
}
YourClass(const std::vector<std::pair<std::string,pMember_t>>& m){
const MetaData& md = myMetaData();
for(MetaData::const_iterator i = md.begin();i!= md.end();++i){
this->*(i->second) = m[i->first];
}
}
};
(pretty sure I've got the syntax right but this is a machinery post not a code post)
RE:
in a function, each member has the same exact code done to it as other members, e.g. assignment from a map in a constructor where map key is same as member key
this is handled above.
RE:
The list of members is very fluid, with constant additions and sometimes deletions, some (but not all) driven by changing columns in a DB table.
When you add a new AMember, say newMember, all you have to do is update the MetaData constructor with an:
push_back(make_pair(std::string("newMember"),&YourClass::newMember));
RE:
This identicality of behavior is repeated across many-many functions (>20), of course the behavior in each function is different so there's no way to factor things out.
You have the machinery to apply this same idiom to build the functions
eg: setAllValuesTo(const AMember& value)
YourClass::setAllValuesTo(const AMember& value){
const MetaData& md = myMetaData();
for(MetaData::const_iterator i = md.begin();i!= md.end();++i){
this->*(i->second) = value;
}
}
If you are a tiny bit creative with function pointers or template functionals you can factor out the mutating operation and do just about anything you want to YourClass' AMember's on a collection basis. Wrap these general functions (that may take a functional or function pointer) to implement your current set of 20 public methods in the interface.
If you need more metadata just augment the codomain of the MetaData map beyond a pointer to member. (Of course the i->second above would change then)
Hope this helps.
You can do something like his:
#define DOTHAT(m) m = map[#m]
DOTHAT(member1); DOTHAT(member2);
#undef DOTHAT
That doesn't fully fit your description, but closest to it that saves you typing.
Probably what I'd look to do would be to make use of runtime polymorphism (dynamic dispatch). Make a parent class for those members with a method that does the common stuff. The members derive their class from that parent class. The ones that need a different implementation of the method implement their own. If they need the common stuff done too, then inside the method they can downcast to the base class and call its version of the method.
Then all you have to do inside your original class is call the member for each method.
I would recommend a small command-line app, written in whatever language you or your team are most proficient in.
Add some kind of template language to your source files. For something like this, you don't need to implement a full-fledged parser or anything fancy like that. Just look for an easily-identified character at the beginning of a line, and some keywords to replace.
Use the command-line app to convert the templated source files into real source files. In most build systems, this should be pretty easy to do automatically by adding a build phase, or simply telling the build system: "use MyParser.exe to handle files of type *.tmp"
Here's an example of what I'm talking about:
MyClass.tmp
MyClass::MyClass(SomeMap & map) { // construct an object from a map
▐REPLACE_EACH, LABEL, "intMember1", "intMember2, ... , "intMemberN"
▐ LABEL = map["$Label"];
}
I've used "▐" as an example, but any character that would otherwise never appear as the first character on a line is perfectly acceptable.
Now, you would treat these .tmp files as your source files, and have the actual C++ code generated automatically.
If you've ever heard the phrase "write code that writes code", this is what it means :)
There are already a lot of good answers and ideas here, but for the sake of diversity I'll present another.
In the code file for MyClass would be:
struct MemberData
{
size_t Offset;
const char* ID;
};
static const MemberData MyClassMembers[] =
{
{ offsetof(MyClass, Member1), "Member1" },
{ offsetof(MyClass, Member2), "Member2" },
{ offsetof(MyClass, Member3), "Member3" },
};
size_t GetMemberCount(void)
{
return sizeof(MyClassMembers)/sizeof(MyClassMembers[0]);
}
const char* GetMemberID(size_t i)
{
return MyClassMembers[i].ID;
}
int* GetMemberPtr(MyClass* p, size_t i) const
{
return (int*)(((char*)p) + MyClassMembers[i].Offset);
}
Which then makes it possible to write the desired constructor as:
MyClass::MyClass(SomeMap& Map)
{
for(size_t i=0; i<GetMemberCount(); ++i)
{
*GetMemberPtr(i) = Map[GetMemberID(i)];
}
}
And of course, for any other functions operating on all the members you would write similar loops.
Now there are a few issues with this technique:
Operations on members use a runtime loop as opposed to other solutions which would yield an unrolled sequence of operations.
This absolutely depends on each member having the same type. While that was allowed by OP, one should still evaluate whether or not that might change in the future. Some of the other solutions don't have this restriction.
If I remember correctly, offsetof is only defined to work on POD types by the C++ standard. In practice, I've never seen it fail. However I haven't used all the C++ compilers out there. In particular, I've never used GCC. So you would need to test this in your environment to ensure it actually works as intended.
Whether or not any of these are problems is something you'll have to evaluate against your own situation.
Now, assuming this technique is usable, there is one nice advantage. Those GetMemberX functions can be turned into public static/member functions of your class, thus providing this generic member access to more places in your code.
class MyClass
{
public:
MyClass(SomeMap& Map);
int Member1;
int Member2;
int Member3;
static size_t GetMemberCount(void);
static const char* GetMemberID(size_t i);
int* GetMemberPtr(size_t i) const;
};
And if useful, you could also add a GetMemberPtrByID function to search for a given string ID and return a pointer to the corresponding member.
One disadvantage with this idea so far is that there is a risk that a member could be added to the class but not to the MyClassMembers array. However, this technique could be combined with xtofl's macro solution so that a single list could populate both the class and the array.
changes in the header:
#define MEMBERS\
MEMBER( Member1 )\
SEP MEMBER( Member2 )\
SEP MEMBER( Member3 )\
class MyClass
{
public:
#define SEP ;
#define MEMBER( name ) int name
MEMBERS;
#undef MEMBER
#undef SEP
// other stuff, member functions, etc
};
and changes in the code file:
const MemberData MyClassMembers[] =
{
#define SEP ,
#define MEMBER( name ) { offsetof(MyClass, name), #name }
MEMBERS
#undef MEMBER
#undef SEP
};
Note: I have left error checking out of my examples here. Depending on how this would be used, you might want to ensure the array bounds are not overrun with debug mode asserts and/or release mode checks that would return NULL pointers for bad indexes. Or some use of exceptions if appropriate.
Of course, if you aren't worried about error checking the array bounds, then GetMemberPtr could actually be changed into something else that would return a reference to the member.

How to get C++ object name in run time?

Can I get an object's name in run time (like getting an object's type via RTTI)? I want the object to be able to print its name.
Since objects in C++ don't have any names, you cannot get them. The only thing you can get to identify an object is its address.
Otherwise, you can implement your naming scheme (which means the objects would have some char* or std::string member with their name). You can inspire yourself in Qt with their QObject hierarchy, which uses a similar approach.
Its not possible. For on thing, an object doesn't have a unique name.
A a;
A& ar = a; // both a and ar refer to the same object
new A; // the object created doesn't have a name
A* ap = new A[100]; // either all 100 objects share the same name, or need to
// know that they are part of an array.
Your best bet is to add a string argument to the objects constructor, and give it a name when its created.
This may be GCC-specific:
#include <typeinfo>
#include <iostream>
template <typename T>
void foo(T t)
{
std::cout << typeid(t).name() << std::endl;
}
The language does not give you access to that information.
By the time the code has been compiled all named objects have been translated into relative memory locations. And even these locations overlap because of optimization (ie once a variable is no longer in use its space can be used by another variable).
The information you need is stored in the debug symbols that are generated by most compilers but these are usually stripped from release versions of the executable so you can not guarantee they exist.
Even if the debug symbols existed they are all compiler/platform specfic so your code would not be portable between OS or even compilers on the same OS. If you really want to follow this course you need to read and understand how the debugger for your platform works (unless you have already written a compiler this is very non trivial).
C++ doesn't really support reflection. However, a bit of googling produced a couple of alternate methods, I doubt you will find them useful though.
C++ objects don't have 'names' (unless I am understanding the problem wrong) Your best hope is to name them as you make them.
class NamedObject
{
String name;
NamedObject(String argname)
{
name = argname;
}
}
NamedObject phil("phil");
If you mean the name of the variable, I don't think this is possible. Maybe if you compile with the GNU Debugger option on ... but even in that way I don't think the language have constructs to do that.
So, this is basically what I did. It's hacky, but it does the trick. I created a variadic macro that takes advantage of stringizing. Unfortunately, it becomes clumsy with the need for a _dummy parameter in order to provide the pseudo-default ctor, because you cannot omit the comma separating the named argument from the variable arguments (I even tried with gnu cpp, but was unsucessful--may I didn't try hard enough).
#include <string>
#define MyNamedClass( objname, ... ) MyClass objname(__VA_ARGS__, #objname )
class MyClass
{
public:
MyClass( void* _dummy=nullptr, const std::string& _name="anonymous") : name( _name ) {}
MyClass( int i, const std::string& _name="anonymous" ) : name( _name ) {}
private:
std::string name;
};
int main()
{
MyClass mc0;
MyClass mc1(54321);
MyNamedClass( mc2, nullptr);
MyNamedClass( mc3, 12345 );
return 0;
}