调用虚拟成员类的方法

时间:2018-06-04 15:29:10

标签: c++ oop inheritance

我知道virtual如何在成员函数的上下文中工作,但我在网上看到一篇关于虚拟成员类的文章让我感到困惑。

我发现的例子是:

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";
        }
    };
};

https://en.wikipedia.org/wiki/Virtual_class上的文章声称:

  

可以以相同的方式访问类类型Machine的任何对象。程序员可以询问轮子的数量(通过调用get_Wheels()),而不需要知道它是什么类型的机器,机器有多少个轮子,或者所有可能类型的机器。像get_Fuel_Type()这样的函数可以通过派生类Car添加到虚拟类Parts。

如何从get_Wheels()调用成员类Parts中的Machine*或任何其他功能?由于您无法保证函数具有实现,因此您似乎必须知道在调用Machine之前您拥有的get_wheels()是什么类型。

4 个答案:

答案 0 :(得分:3)

对不起,我的朋友,但C ++在这个意义上没有“虚拟课程”。它具有虚拟的类,因为它们具有一些纯虚方法,因此它们无法实例化(参见this question) - 但不是您所描述的内容。

正如@StephenMWebb指出的那样 - 您链接到的维基百科文章并未声称是关于C ++的......

答案 1 :(得分:3)

您发布的代码不是C ++,因为此语言不支持您描述的概念中的虚拟类

答案 2 :(得分:0)

让我们将其转换为真正的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!
{
};

在C ++中,没有地方或需要“虚拟类”的概念。任何类都可以继承任何其他类(无论是否内部),只要它是可访问的,就像上面的示例一样。如你所见,即使完全不相关的类也可以从内部类继承......

另一方面,如果我们希望能够覆盖,我们需要显式地声明函数虚拟 - 好吧,第一个被覆盖的至少,实际上覆盖的那些是隐式的虚拟。长期以来一直被认为是重写虚拟甚至覆盖函数的好习惯,因为C ++ 11是冗余的,因为override关键字也意味着虚拟性......显然,在本文的示例语言中,函数总是如此隐含虚拟...

答案 3 :(得分: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;
}