-2

My question is as follows:

I want (if it is possible) to "implement" virtual functions without using the "virtual" keyword (out of curiosity - I know the trick with functions pointers in C , I wish to do that in C++ !!). My "idea" is to have a flag which will be assigned in the constructor in order to indicate which instance this object is. My questions are: 1)Is it even possible ? 2)If so - what am I doing wrong ? or what is missing ?

I am using g++ which gives me these errors:

#‘B’ has not been declared

#‘C’ has not been declared

#class ‘B’ does not have any field named ‘flag’

#class ‘C’ does not have any field named ‘flag’

This is My suggestion:

#include <iostream>
using namespace std;

class A {

protected:
    short flag;
public:
   A(int f = 1) : flag(f) {}
   void foo() 
   {
      switch (this->flag)
     {
        case 1: cout << "A " << endl; break;

        case 2: B :: foo(); break;

        case 3: C :: foo(); break;
     }
   }
};

class B : public A{

public:
B(int f = 2) : A(f) {}
void foo() {cout << "B " << endl;}
};


class C : public B{

 public:
   C(int f = 3) : B(f) {}
   void foo() {cout << "C " << endl;}
};

int main()
{
  A a;
  B b;
  C c;

  A *pb = &b;
  A *pc = &c;

  a.foo();
  pb->foo();
  pc->foo();

  return 0;
} // end main   

Thanks allot (!!) in advance , Guy.

Guy Avraham
  • 3,482
  • 3
  • 38
  • 50
  • 3
    Just one question: why? Is this an XY problem? –  Nov 29 '13 at 17:28
  • 1
    C++ has the virtual keyword exactly so that you don't have to do this. – Raymond Chen Nov 29 '13 at 17:41
  • Certainly doable, c-front used ot implement all the C++ Object stuff, including dynamic dispatch for virtuals with C code just fine. Of course, its not advisable, vtables are a pain to create and manage, and switch statements are an abomination. – RichardPlunkett Nov 29 '13 at 17:41
  • I you really want to have polymorphism and absolutely no vtable, use [CRTP](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)s! – πάντα ῥεῖ Nov 29 '13 at 17:45
  • @H2CO3: For fun, perhaps? – Lightness Races in Orbit Nov 29 '13 at 17:52
  • @LightnessRacesinOrbit I hope. If this was meant to be production code, then something is wrong. –  Nov 29 '13 at 17:56
  • Unless you give a reason *why* you don't want a vtable, this is not a practical question but rather a theoretical exercise. SO is for practical problems, not theoretical ones. In practice, you would just use a vtable. (And when you tell us why you don't want a vtable, we may be able to come up with a design that lets you use a vtable after all.) – Raymond Chen Dec 03 '13 at 14:55
  • @Raymond Chen This is merely an interview question (I guess I should have mentioned it...) - so , please if you can come up with a solution it would be great. Thanks alot !! – Guy Avraham Dec 03 '13 at 15:36
  • 1
    If somebody asked me this in an interview, I would ask why vtables are not allowed and try to see if we can architect a solution that uses the language as it was designed rather than reimplementing language features. Besides, you say that you know how to do this in C with function pointers. So use that solution in C++. Function pointers work in C++ too. – Raymond Chen Dec 03 '13 at 16:04

1 Answers1

1

Is it even possible ?

Yes. It may not be advisable, since it's more error-prone than virtual functions, and requires the base class to know about all of the derived classes, but it's certainly possible, and you're almost there.

If so - what am I doing wrong ?

You'll need to move the definition of A::foo out of the class, after the definitions of B and C, so that it can use those classes.

You'll need an explicit downcast to access member functions of derived classes:

static_cast<B*>(this)->foo();
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644