Re: vb6 style "implements interface"
On 27 Feb., 13:46, mick.mcma...@gmail.com wrote:
Hi, i need some help, i'm new-ish to c++ but was an experienced VB6
programmer.
I am trying to do something in c++ along the lines of something i did
a couple of years ago in vb.
Basically, i have loads classes, and want to store them in some sort
of array/container and enumerate through them and call a couple of
methods. I don't need to know which one i'm calling.
In VB i use an shell class and with all the methods that i wanted to
call. then created my other classes implementing the shell interface.
I stored them all in a collection and went through them by creating a
class varible of the interface type and then storing the class from
the collection into it and calling the methods.
I've spent a couple of days looking now, and it's either impossible or
i just don't know the teminolgy for how to do it.
Any help much appreciated.
Mick.
While C++ does not have an explicit "interface" keyword like Java or
C#, an abstract base class is the appropriate equivalent:
class Shell {
public:
virtual int method1( int, char ) = 0;
virtual void method2() = 0;
...
};
class Derived1 : public Shell {
public:
int method1( int x, char c ) { ... }
void method2() { ... }
};
class Derived2 : public Shell {
public:
int method1( int x, char c ) { ... }
void method2() { ... }
};
Note the "= 0" declaration. This enforces an implementation for any
derived class for that you want to create an actual object.
Alternatively you can define real implementations in class Shell that
get used as defaults if a derived class does not offer an
implementation on its own.
In your application, you can create instances of Derived1 and Derived2
and store pointers to them in a common container for objects of class
Shell:
std::list<Shell*> mycontainer;
mycontainer.push_back( new Derived1 );
mycontainer.push_back( new Derived2 );
Note, you cannot use a std::list<Shell>, you need to dereference
pointers here.
You can iterate through the list and calling methods will resolve
dependend on the derived type Derived1 resp. Derived2:
for ( std::list<Shell*>::iterator p = mycontainer.begin(); p !=
mycontainer.end(); ++p ) {
std::cout << (*p)->method1( 1, 'x' ) << std::endl;
(*p)->method2();
}
or, if you prefer STL functor style:
class f {
public:
void operator() ( Shell* p ) {
std::cout << p->method1( 1, 'x' ) << std::endl;
p->method2();
}
};
....
std::for_each( mycontainer.begin(), mycontainer.end(), f() );
best,
Michael.