2

I know how virtual works in the context of member functions, but I saw an article online about virtual member classes that confuses me.

The example I found is this:

class Machine
{
    void run () {}

    virtual class Parts
    {
    };
};

// The inner class "Parts" of the class "Machine" may return the number of wheels the machine has.
class Car: public Machine
{
    void run() { 
        cout << "The car is running." << endl; 
    }
    class Parts
    {
        int get_Wheels () {
            cout << "A car has 4 wheels." << endl;
            return 4;
        }
        string get_Fuel_Type () {
            cout << "A car uses gasoline for fuel." << endl;
            return "gasoline";
        }
    };
};

The article at https://en.wikipedia.org/wiki/Virtual_class claims:

Any object of class type Machine can be accessed the same way. The programmer can ask for the number of wheels (by calling get_Wheels()), without needing to know what kind of machine it is, how many wheels that machine has, or all the possible types of machines there are. Functions like get_Fuel_Type() can be added to the virtual class Parts by the derived class Car.

How can one call get_Wheels() or any other function in the member class Parts from a Machine*? It seems like you would have to know what kind of Machine you have before being able to call get_wheels() since you have no guarantee that the function has an implementation.

samuelnj
  • 1,627
  • 1
  • 10
  • 19

4 Answers4

3

I'm sorry, my friend, but C++ doesn't have "virtual classes" in this sense. It has classes that are virtual in that they have some pure-virtual methods, so they can't be instantiated (see this question) - but not what you're describing.

As @StephenMWebb points out - the Wikipedia article you linked to does not claim to be about C++...

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 1
    Hm, I know this as "abstract" classes, never heard of them being called "virtual" before... – Aconcagua Jun 04 '18 at 15:40
  • Seconding @Aconcagua. Additionally, a class with virtual functions (pure or not) is also a polymorphic class. – Quentin Jun 04 '18 at 15:40
  • @Quentin: See link. – einpoklum Jun 04 '18 at 15:57
  • @einpoklum Virtual ***base*** class, i, e. we are speaking of virtual *inheritance*, entirely different matter... – Aconcagua Jun 04 '18 at 15:59
  • @einpoklum oh, I see. That's [virtual base] class, in that the inheritance (and thus the base-ness) is virtual, not the class. – Quentin Jun 04 '18 at 15:59
  • @Aconcagua: Well, a "virtual base classes" is a *class*, and it's *virtual* in a way, so... you know. Cause for confusion. – einpoklum Jun 04 '18 at 16:14
  • 1
    @einpoklum Haha - time for playing ["Teekesselchen"](https://de.wikipedia.org/wiki/Teekesselchen) Sorry for German link, don't know how this game is called in English (or if played at all in Anglo-Saxon circles). – Aconcagua Jun 04 '18 at 16:34
3

The code you posted is not C++, since this language doesn't support virtual classes in the notion that you describe.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
0

Let's transform this to real C++:

class Machine
{
    // need to make it explicitly virtual, otherwise subclasses
    // cannot override, just hide!
    virtual void run () { }

protected:      // otherwise, not accessible from sub classes!
    class Parts // no keyword virtual!!!
    {
    };
};

class Car : public Machine
{
    virtual void run() override
    { 
        cout << "The car is running." << endl; 
    }

    class Parts : Machine::Parts
    //          ^ but we need to inherit  e x p l i c i t l y
    {
        int get_Wheels ();
        std::string get_Fuel_Type();
    }
};

class JustADemo : public Machine::Parts // Parts needs to be public for!
{
};

In C++, there is no place or need for a concept of "virtual classes". Any class can inherit from any other (no matter if inner or not), as long as it is accessible, just as in the samples above. As you see, even totally unrelated classes can inherit from inner classes...

On the other hand, if we want to be able to override, we need to explicitly declare functions virtual – well, the first one to be overridden at least, actually overriding ones then are virtual implicitly. Was long considered good practice to repeat the virtual even on overriding functions, since C++11 redundant, though, as override keyword implies virtuality as well... Apparently, in the sample language in the article, functions always are implicitly virtual...

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
0

Another effort:

class Parts {
public:
    virtual int get_Wheels() = 0;
    virtual string get_Fuel_Type() = 0;
};

class CarParts: public Parts
{
public:
    virtual int get_Wheels() override {
        cout << "A car has 4 wheels." << endl;
        return 4;
    }
    virtual string get_Fuel_Type() override {
        cout << "A car uses gasoline for fuel." << endl;
        return "gasoline";
    }
};

class Machine
{
public:
    virtual void run() = 0;
};


class Car : public Machine, public CarParts{
public:
     virtual void run()  {
        cout << "The car is running." << endl;
    }
};

int main() {
    Machine* ptr = new Car();
    reinterpret_cast<Car*>(ptr)->run();
    reinterpret_cast<Car*>(ptr)->get_Wheels();
    return 0;
}
seccpur
  • 4,996
  • 2
  • 13
  • 21