This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| 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.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.