代码之家  ›  专栏  ›  技术社区  ›  samuelnj

虚拟成员类的调用方法

  •  1
  • samuelnj  · 技术社区  · 7 年前

    我知道如何 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()),而无需知道它是什么类型的机器,机器有多少轮子,或者所有可能的机器类型。派生类car可以将get_fuel_type()等函数添加到虚拟类部件中。

    怎么能打电话 get_Wheels() 或成员类中的任何其他函数 Parts 从A Machine* ?看来你得知道 Machine 你还没来得及打电话 get_wheels() 因为你不能保证函数有一个实现。

    4 回复  |  直到 7 年前
        1
  •  3
  •   gsamaras a Data Head    7 年前

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

        2
  •  3
  •   einpoklum    7 年前

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

    正如StephenMWebb指出的,你链接到的维基百科文章并没有声称是关于C++的。

        3
  •  0
  •   Aconcagua    7 年前

    让我们把它转换成真正的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++中,对于“虚拟类”的概念没有地方或需要。任何类都可以从任何其他类继承(无论是否内部),只要它是可访问的,就像上面的示例一样。如您所见,即使是完全不相关的类也可以从内部类继承…

    另一方面,如果我们希望能够重写,我们需要显式地声明函数为virtual——好吧,至少要重写第一个函数,实际上重写的函数是virtual隐式的。长期以来被认为是很好的做法,即使在重写函数上重复虚拟,因为C++ 11冗余,但是,作为 override 关键字也意味着虚拟性…显然,在本文的示例语言中,函数总是隐式虚拟的…

        4
  •  0
  •   seccpur    7 年前

    另一项努力:

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