Shing Yip
Shing Yip

Reputation: 1626

Dynamic C++

I'm wondering about an idea in my head. I want to ask if you know of any library or article related to this. Or you can just tell me this is a dumb idea and why.

I have a class, and I want to dynamically add methods/properties to it at runtime. I'm well aware of the techniques of using composite/command design pattern and using embedded scripting language to accomplish what I'm talking about. I'm just exploring the idea. Not necessary saying that it is a good idea.

class Dynamic
{
public:
    typedef std::map<std::string, boost::function<void (Dynamic&)> > FuncMap;

    void addMethod(const std::string& name, boost::function<void (Dynamic&)> func) {
        funcMap_[name] = func;
    }

    void operator[](const std::string& name) {
        FuncMap::iterator funcItr = funcMap_.find(name);
        if (funcItr != funcMap_.end()) {
            funcItr->second(*this);
        }
    }

private:
    FuncMap funcMap_;
};

void f(Dynamic& self) {
    doStuffWithDynamic(self);
}

int main()
{
    Dynamic dyn;
    dyn.addMethod("f", boost::bind(&f, _1));
    dyn["f"]; // invoke f
}

The idea is that I can rebind the name "f" to any function at runtime. I'm aware of the performance problem in string lookup and boost::function vs. raw function pointer. With some hard work and non-portable hack I think I can make the performance problem less painful.

With the same kind of technique, I can do "runtime inheritance" by having a "v-table" for name lookup and dispatch function calls base on dynamic runtime properties.

If just want to tell me to use smalltalk or Objective-C, I can respect that but I love my C++ and I'm sticking with it.

Upvotes: 0

Views: 558

Answers (8)

Daniel Earwicker
Daniel Earwicker

Reputation: 116674

If you implemented this, even as a pure library, and then used it extensively, you would in a way be using a new language - one with a hideous syntax, and a curious combination of runtime method resolution and unreliable bounds checking.

As a fan of C/C++ style syntax and apparently a fan of dynamic method dispatch, you may be interested in C# 4.0, which is now in Beta, and has the dynamic keyword to allow exactly this kind of thing to be seamlessly mixed into normal statically typed code.

Upvotes: 3

zdan
zdan

Reputation: 29450

If I understand what you are trying to accomplish correctly, it seems as though dynamic linking (i.e. Dynamically loaded libraries in windows or linux) will do most of what you are trying to accomplish.

That is, you can, at runtime, select the name of the function you want to execute (eg. the name of the DLL), which then gets loaded and executed. Much in the way that COM works. Or you can even use the name of the function exported from that library to select the correct function (C++ name mangling issues aside).

Upvotes: 1

Max Lybbert
Max Lybbert

Reputation: 20041

I've considered doing this before as well. Basically, however, you'd be on your way to writing a simple VM or interpreter (look at, say, Lua or Topaz's source to see what I mean -- Topaz is a dead project that pre-dates Parrot).

But if you're going that route it makes sense to just use an existing VM or interpreter.

Upvotes: 0

StackedCrooked
StackedCrooked

Reputation: 35485

What you are doing is actually a variation of the Visitor pattern.

EDIT: By the way, another approach would be by using Lua, since the language allows you to add functions at runtime. So does Objective-C++.

EDIT 2: You could actually inherit from FuncMap as well:

class Dynamic;

typedef std::map<std::string, boost::function<void (Dynamic&)> > FuncMap;

class Dynamic : public FuncMap
{
public:
};

void f(Dynamic& self) {
    //doStuffWithDynamic(self);
}

int main()
{
    Dynamic dyn;
    dyn["f"] = boost::bind(&f, _1);
    dyn["f"](dyn); // invoke f, however, 'dyn'param is awkward...
    return 0;
}

Upvotes: 1

Drew Hoskins
Drew Hoskins

Reputation: 4186

I keep thinking of the Visitor pattern. That allows you to do a vtable lookup on the visiting object (as well as the visited object, thought that doesn't seem relevant to your question).

And at runtime, you could have some variable which refers to the visitor, and call

Dynamic dynamic;
DynamicVisitor * dv = ...;
dynamic->Accept(dv);
dv = ...; // something else
dynamic->Accept(dv);

The point is, the visitor object has a vtable, which you said you wanted, and you can change its value dynamically, which you said you wanted. Accept is basically the "function to call things I didn't know about at compile time."

Upvotes: 0

Michael Kohne
Michael Kohne

Reputation: 12044

What you want is to change C++ into something very different. One of the (many) goals of C++ was efficient implementation. Doing string lookup for function calls (no matter how well you implement it), just isn't going to be very efficient compared to the normal call mechanisms.

Basically, I think you're trying to shoehorn in functionality of a different language. You CAN make it work, to some degree, but you're creating C++ code that no one else is going to be able (or willing) to try to understand.

If you really want to write in a language that can change it's objects on the fly, then go find such a language (there are many choices, I'm sure). Trying to shoehorn that functionality into C++ is just going to cause you problems down the road.

Please note that I'm no stranger to bringing in non-C++ concepts into C++. I once spent a considerable amount of time removing another engineer's attempt at bringing a based-object system into a C++ project (he liked the idea of containers of 'Object *', so he made every class in the system descend from his very own 'Object' class).

Bringing in foreign language concepts almost always ends badly in two ways: The concept runs up against other C++ concepts, and can't work as well as it did in the source language, AND the concept tends to break something else in C++. You end up losing a lot of time trying to implement something that just isn't going to work out.

The only way I could see something like this working at all well, is if you implemented a new language on top of C++, with a cfront-style pre-compiler. That way, you could put some decent syntax onto the thing, and eliminate some of your problems.

Upvotes: 8

David Thornley
David Thornley

Reputation: 57036

I don't think it would be a good idea to change C++ enough to make this work. I'd suggest working in another language, such as Lisp or Perl or another language that's basically dynamic, or imbedding a dynamic language and using it.

Upvotes: 2

rlbond
rlbond

Reputation: 67749

I don't think there's a library for this exact thing.

Of course, you have to have these functions pre-written somehow, so it seems there would be an easier way to do what you want. For example you could have just one method to execute arbitrary code from your favorite scripting language. That seems like an easier way to do what you want.

Upvotes: 0

Related Questions