juli (caladri) wrote in dailysrc,
juli
caladri
dailysrc

doing interface-based programming in C++.

In C++, I've wanted do do interface-based programming, and further, be able to wrap things at the interface level so that I could make locking part of the interface, or possibly do an asynchronous or remote function call without the caller having to know or do anything special. A few weeks ago I came up with a way to do this by stacking vtables. Note that this version is simple and uses two virtual methods. A more complex version uses a templated IBase to avoid one virtual method, which should be fairly obvious. Note that this is cumbersome, but I've written (and am using) a proof-of-concept interface generator to do this stuff for me, and I've already begun using it to make invariants and locking and whatnot a part of the exported interface/contract in my code.

Note that this is also a good interview question, if you're so inclined. I came up with this with a lot of help from arjache.

#include <iostream>

class Base {
protected:
        Base(void)
        {
                std::cout << __PRETTY_FUNCTION__ << std::endl;
        }

        virtual ~Base()
        {
                std::cout << __PRETTY_FUNCTION__ << std::endl;
        }
public:
        void method(const char *string)
        {
                std::cout << __PRETTY_FUNCTION__ << std::endl;
                methodWrapper(string);
                std::cout << __PRETTY_FUNCTION__ << std::endl;
        }
private:
        virtual void methodWrapper(const char *) = 0;
};

class IBase : public Base {
protected:
        IBase(void)
        {
                std::cout << __PRETTY_FUNCTION__ << std::endl;
        }

        virtual ~IBase()
        {
                std::cout << __PRETTY_FUNCTION__ << std::endl;
        }
private:
        void methodWrapper(const char *string)
        {
                std::cout << __PRETTY_FUNCTION__ << std::endl;
                method(string);
                std::cout << __PRETTY_FUNCTION__ << std::endl;
        }
        virtual void method(const char *) = 0;
};

class MyClass : public IBase {
public:
        MyClass(void)
        {
                std::cout << __PRETTY_FUNCTION__ << std::endl;
        }

        ~MyClass()
        {
                std::cout << __PRETTY_FUNCTION__ << std::endl;
        }
private:
        void method(const char *string)
        {
                std::cout << string << std::endl;
        }
};

void
hello(Base *base)
{
        std::cout << __PRETTY_FUNCTION__ << std::endl;
        base->method("Hello, world!");
        std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int
main(void)
{
        MyClass test;
        hello(&test);
        return (0);
}

Subscribe
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

  • 4 comments