C++/inheritance and virtual functions

From Attie's Wiki
Jump to: navigation, search

A good how-to for implementing callbacks in C++

#include <iostream>
#include <string>
using namespace std;
 
/* --- */
 
class c1_i {
	public:
		explicit c1_i(void);
		~c1_i(void);
 
		virtual void c1_callback(void) = 0;
};
 
c1_i::c1_i(void) {
	cout << "c1_i::c1_i\n";
}
c1_i::~c1_i(void) {
	cout << "c1_i::~c1_i\n";
}
 
/* --- */
 
/* c2_i has no constructor / destructor functions */
class c2_i {
	public:
		virtual void c2_callback(void) = 0;
};
 
/* --- */
 
 /* c3_i has a constructor that takes an argument */
class c3_i {
	public:
		explicit c3_i(string message);
 
		string message;
 
		virtual void c3_callback(void) = 0;
};
 
c3_i::c3_i(string message) {
	cout << "c3_i::c3_i\n";
	this->message = message;
}
 
/* --- */
 
class myC: public c1_i, public c2_i, public c3_i {
	public:
		explicit myC(string message);
		~myC(void);
 
		void c1_callback(void);
		void c2_callback(void);
		void c3_callback(void);
};
 
myC::myC(string message): c3_i(message) {
	cout << "myC::myC\n";
}
myC::~myC(void) {
	cout << "myC::~myC\n";
}
void myC::c1_callback(void) {
	cout << "myC::c1_callback\n";
}
void myC::c2_callback(void) {
	cout << "myC::c2_callback\n";
}
void myC::c3_callback(void) {
	cout << "myC::c3_callback: " << message << "\n";
}
 
/* --- */
 
class t1 {
	public:
		explicit t1(c1_i *i);
		~t1(void);
 
		void exec(void);
 
	private:
		c1_i *i;
};
t1::t1(c1_i *i) {
	if (i == NULL) throw(-1);
	this->i = i;
	cout << "t1::t1\n";
}
t1::~t1(void) {
	cout << "t1::~t1\n";
}
void t1::exec(void) {
	cout << "t1::exec\n";
	i->c1_callback();
}
 
/* --- */
 
class t2 {
	public:
		explicit t2(c2_i *i);
		~t2(void);
 
		void exec(void);
 
	private:
		c2_i *i;
};
t2::t2(c2_i *i) {
	if (i == NULL) throw(-1);
	this->i = i;
	cout << "t2::t2\n";
}
t2::~t2(void) {
	cout << "t2::~t2\n";
}
void t2::exec(void) {
	cout << "t2::exec\n";
	i->c2_callback();
}
 
/* --- */
 
class t3 {
	public:
		explicit t3(c3_i *i);
		~t3(void);
 
		void exec(void);
 
	private:
		c3_i *i;
};
t3::t3(c3_i *i) {
	if (i == NULL) throw(-1);
	this->i = i;
	cout << "t3::t3\n";
}
t3::~t3(void) {
	cout << "t3::~t3\n";
}
void t3::exec(void) {
	cout << "t3::exec\n";
	i->c3_callback();
}
 
/* --- */
 
int main(int argc, char *argv[]) {
	myC m("howdy");
 
	m.c1_callback();
	m.c2_callback();
	m.c3_callback();
 
	t1 t(&m);
	t.exec();
 
	t2 tt(&m);
	tt.exec();
 
	t3 ttt(&m);
	ttt.exec();
 
	cout << "hi\n";
	return 0;
}

Expected output

$ g++ test.cpp -o test && ./test
c1_i::c1_i
c3_i::c3_i
myC::myC
myC::c1_callback
myC::c2_callback
myC::c3_callback: howdy
t1::t1
t1::exec
myC::c1_callback
t2::t2
t2::exec
myC::c2_callback
t3::t3
t3::exec
myC::c3_callback: howdy
hi
t3::~t3
t2::~t2
t1::~t1
myC::~myC
c1_i::~c1_i
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox