Re: base classes and inheritance problem
zionztp@gmail.com wrote in
news:13963af3-7f85-4b17-bba1-ec6637846f0f@n77g2000hse.googlegroups.com:
[...]
Thanks for your reply, well my example was pretty bad (both code and
as example), so i will try with another:
#include <iostream>
using namespace std;
class A
{
public:
A(){n=5;}
virtual void show() = 0;
protected:
int n;
};
class B : public A
{
public:
void show(){cout << n << endl;}
};
class C : public A
{
public:
void show(){cout << n*2 << endl;}
};
int main()
{
A *c;
int class_num = 0; //user input
if(class_num == 0){
c = new B();
}else{
c = new C();
}
c->show();
delete c;
return 0;
}
Considering this example, what would be the best way if i wanted to
avoid virtual functions? of course i've reconsidered the use of
virtual functions since it may be totally unneeded optimization to
avoid them, but im just curious about this right now, and yes you are
right im not very used to C++ i mainly use it as an "extended" C.
Since you asked, and since you are curious - don't use the examples below
in real work!
Way 1:
B* try_b = dynamic_cast<B*>(c);
if (try_b) {
try_b->B::show();
} else {
static_cast<C*>(c)->C::show();
}
Here you still need at least one virtual function in A class for
dynamic_cast to work. The explicit B::show() and C::show are for avoiding
virtual call in case A::show() is virtual, it it's not, the class names
can be dropped.
Note that this is more ugly and more cumbersome than virtual function
calls. Also, dynamic_cast might well be slower than virtual dispatch,
unless you can haul it out of a tight loop.
Way 2:
class A {
public:
int type_;
// ... rest of A as in your example
};
class B: public A {
public:
B() {type_=1;}
// ...
};
class C: public A {
public:
C() {type_=2;}
// ...
};
// ...
A *c = ... // new B or C
switch(c->type_) {
case 1:
static_cast<B*>(c)->B::show();
break;
case 2:
static_cast<C*>(c)->C::show();
break;
}
(The same here: if the show function is not virtual, the class prefixes
in function names can be dropped. The switch might well be not faster
than the virtual function call, unless you can haul the switch out of a
tight loop.)
Way 3:
#include <iostream>
class A {
public:
void (*show_ptr_)(A*);
A(): n_(5) {}
int n_;
};
void show_B(A* a) {
std::cout << a->n_ << "\n";
}
class B: public A {
public:
B() { show_ptr_ = show_B; }
};
void show_C(A* a) {
std::cout << 2*a->n_ << "\n";
}
class C: public A {
public:
C() { show_ptr_ = show_C; }
};
int main() {
A *c = new C();
(*c->show_ptr_)(c);
}
This is emulating the virtual dispatch and most probably having the same
or worse performance. Hauling the decision out of the loop is not really
possible here. This approach is sometimes used in C language for
emulating C++ virtual methods.
hth
Paavo