C++/inheritance and virtual functions
From Attie's Wiki
(Difference between revisions)
m |
m |
||
(2 intermediate revisions by one user not shown) | |||
Line 3: | Line 3: | ||
<source lang="cpp"> | <source lang="cpp"> | ||
#include <iostream> | #include <iostream> | ||
+ | #include <string> | ||
using namespace std; | using namespace std; | ||
− | + | ||
/* --- */ | /* --- */ | ||
− | + | ||
class c1_i { | class c1_i { | ||
public: | public: | ||
explicit c1_i(void); | explicit c1_i(void); | ||
~c1_i(void); | ~c1_i(void); | ||
− | + | ||
virtual void c1_callback(void) = 0; | virtual void c1_callback(void) = 0; | ||
}; | }; | ||
− | + | ||
c1_i::c1_i(void) { | c1_i::c1_i(void) { | ||
cout << "c1_i::c1_i\n"; | cout << "c1_i::c1_i\n"; | ||
Line 21: | Line 22: | ||
cout << "c1_i::~c1_i\n"; | cout << "c1_i::~c1_i\n"; | ||
} | } | ||
− | + | ||
/* --- */ | /* --- */ | ||
− | + | ||
+ | /* c2_i has no constructor / destructor functions */ | ||
class c2_i { | class c2_i { | ||
public: | public: | ||
− | |||
− | |||
− | |||
virtual void c2_callback(void) = 0; | virtual void c2_callback(void) = 0; | ||
}; | }; | ||
− | + | ||
− | + | /* --- */ | |
− | + | ||
− | } | + | /* c3_i has a constructor that takes an argument */ |
− | + | class c3_i { | |
− | cout << " | + | 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 { | + | class myC: public c1_i, public c2_i, public c3_i { |
public: | public: | ||
− | explicit myC( | + | explicit myC(string message); |
~myC(void); | ~myC(void); | ||
− | + | ||
void c1_callback(void); | void c1_callback(void); | ||
void c2_callback(void); | void c2_callback(void); | ||
+ | void c3_callback(void); | ||
}; | }; | ||
− | + | ||
− | myC::myC( | + | myC::myC(string message): c3_i(message) { |
cout << "myC::myC\n"; | cout << "myC::myC\n"; | ||
} | } | ||
Line 62: | Line 72: | ||
cout << "myC::c2_callback\n"; | cout << "myC::c2_callback\n"; | ||
} | } | ||
− | + | void myC::c3_callback(void) { | |
+ | cout << "myC::c3_callback: " << message << "\n"; | ||
+ | } | ||
+ | |||
/* --- */ | /* --- */ | ||
− | + | ||
class t1 { | class t1 { | ||
public: | public: | ||
explicit t1(c1_i *i); | explicit t1(c1_i *i); | ||
~t1(void); | ~t1(void); | ||
− | + | ||
void exec(void); | void exec(void); | ||
− | + | ||
private: | private: | ||
c1_i *i; | c1_i *i; | ||
Line 78: | Line 91: | ||
if (i == NULL) throw(-1); | if (i == NULL) throw(-1); | ||
this->i = i; | this->i = i; | ||
− | cout << "t1:: | + | cout << "t1::t1\n"; |
} | } | ||
t1::~t1(void) { | t1::~t1(void) { | ||
Line 87: | Line 100: | ||
i->c1_callback(); | i->c1_callback(); | ||
} | } | ||
− | + | ||
/* --- */ | /* --- */ | ||
− | + | ||
class t2 { | class t2 { | ||
public: | public: | ||
explicit t2(c2_i *i); | explicit t2(c2_i *i); | ||
~t2(void); | ~t2(void); | ||
− | + | ||
void exec(void); | void exec(void); | ||
− | + | ||
private: | private: | ||
c2_i *i; | c2_i *i; | ||
Line 103: | Line 116: | ||
if (i == NULL) throw(-1); | if (i == NULL) throw(-1); | ||
this->i = i; | this->i = i; | ||
− | cout << "t2:: | + | cout << "t2::t2\n"; |
} | } | ||
t2::~t2(void) { | t2::~t2(void) { | ||
Line 112: | Line 125: | ||
i->c2_callback(); | 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[]) { | int main(int argc, char *argv[]) { | ||
− | myC m; | + | myC m("howdy"); |
− | + | ||
m.c1_callback(); | m.c1_callback(); | ||
m.c2_callback(); | m.c2_callback(); | ||
− | + | m.c3_callback(); | |
+ | |||
t1 t(&m); | t1 t(&m); | ||
t.exec(); | t.exec(); | ||
− | + | ||
t2 tt(&m); | t2 tt(&m); | ||
tt.exec(); | tt.exec(); | ||
− | + | ||
+ | t3 ttt(&m); | ||
+ | ttt.exec(); | ||
+ | |||
cout << "hi\n"; | cout << "hi\n"; | ||
return 0; | return 0; | ||
Line 136: | Line 178: | ||
$ g++ test.cpp -o test && ./test | $ g++ test.cpp -o test && ./test | ||
c1_i::c1_i | c1_i::c1_i | ||
− | + | c3_i::c3_i | |
myC::myC | myC::myC | ||
myC::c1_callback | myC::c1_callback | ||
myC::c2_callback | myC::c2_callback | ||
− | t1:: | + | myC::c3_callback: howdy |
+ | t1::t1 | ||
t1::exec | t1::exec | ||
myC::c1_callback | myC::c1_callback | ||
− | t2:: | + | t2::t2 |
t2::exec | t2::exec | ||
myC::c2_callback | myC::c2_callback | ||
+ | t3::t3 | ||
+ | t3::exec | ||
+ | myC::c3_callback: howdy | ||
hi | hi | ||
+ | t3::~t3 | ||
t2::~t2 | t2::~t2 | ||
t1::~t1 | t1::~t1 | ||
myC::~myC | myC::~myC | ||
− | |||
c1_i::~c1_i | c1_i::~c1_i | ||
</source> | </source> |
Latest revision as of 19:43, 9 June 2012
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; }
[edit] 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