  | 
   Accessing Class Data Members By Name 
   Submitted by  |   
  
  
First of all, I apologize for my dubious english, my native
language is french.
  
So here is my first COTD submission. The following code provides a
"string" interface for accessing to the data members of an object.
For example, instead of doing sphere->SetRadius(12), you'll just
have to do sphere->SetProperty("radius",12), given that the object
sphere is an instance of a class based on the class I named 'Object'.
  
This mechanism is pretty useful when you write an interpreter for
a description language, say, a scene description language for a
raytracer (this is my case).
  
If you want to compile the following code snip with Visual C++ 6.0
(this comment probably applies to older versions too), make sure you
checked the option "Enable Run-Time Type Information (RTTI)" in the
Project Settings window, C/C++ tab, C++ Language category. I haven't
even tried to compile this with any other compiler, but it should work
since the thing is standard (well, at most part). However, you'll have
to use a reasonably recent compiler which correctly implements the few
features I used.
  
Enjoy and give me your opinion on the usefulness of such a code,
and, especially, tell me if you have a more simple and/or elegant
way to do this. Thank to all of you.
  
Cheers, 
Francois
 | 
 
 
 
Download Associated File: property.cpp (1,441 bytes)
 
 // Francois Beaune
// January 2001
#include <cstring>
#include <iostream>
#include <map>
  using namespace std;
  class CStringCmp {
public:
	bool operator()(const char *s1, const char *s2) {
		return strcmp(s1, s2) < 0;
	}
};
  class Object {
	typedef void (Object::*mptr_double)(double); // pointer to 'Object' method taking double
	
	map<const char *,mptr_double,CStringCmp>
		mm_double;	// map string to method taking double
public:
	virtual void RegisterProperty(const char *name, mptr_double method) {
		mm_double[name] = method;
	}
  	virtual bool SetProperty(const char *name, double value) {
		mptr_double method = mm_double[name];
  		if(method)
			(this->*method)(value);
  		return method;
	}
};
  class Sphere : public Object {
	double radius;
public:
	Sphere(double r) : radius(r) {
		RegisterProperty("radius",mptr_double(&Sphere::SetRadius));
	}
  	void SetRadius(double r) {
		radius = r;
	}
  	double Radius() const {
		return radius;
	}
};
  int main() {
	Sphere *s = new Sphere(1);
  	if(s->SetProperty("radius",10))
		cout << "s->radius set to " << s->Radius() << '.' << endl;
  	if(!s->SetProperty("undefined",1234))
		cout << "The property \"undefined\" does not exist for object 's'." << endl;
  	Object *o = new Sphere(2);
  	if(o->SetProperty("radius",20))
		cout << "o->radius set to " <<
			dynamic_cast<Sphere *>(o)->Radius() << '.' << endl;
  	return 0;
}
   |  
  
 | 
 
 
 
The zip file viewer built into the Developer Toolbox made use
of the zlib library, as well as the zlibdll source additions.
 
 
 |