【问题标题】:Calling methods of a virtual member class调用虚拟成员类的方法
【发布时间】:2018-06-04 15:29:09
【问题描述】:

我知道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 的文章声称:

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

如何从Machine* 调用get_Wheels() 或成员类Parts 中的任何其他函数?似乎您必须知道您拥有什么样的Machine,才能调用get_wheels(),因为您无法保证该函数具有实现。

【问题讨论】:

  • 维基百科文章中没有任何内容表明示例代码是 C++。
  • 这不是合法的 C++ 代码ideone.com/zbih4s
  • @StephenM.Webb 好点,我假设它来自cout的使用
  • @samuelnj 你是正确的混淆。感谢您指出这一点,+1。 wiki 文章需要编辑,但我做不到,所以如果有人可以,请做..
  • 真的很奇怪他们怎么能把那篇文章搞得这么乱。我的意思是代码几乎是C++,你只需要删除virtual,但这就是文章的内容......

标签: c++ oop inheritance


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 嗯,我知道这是“抽象”类,以前从未听说过它们被称为“虚拟”......
    • 第二个@Aconcagua。此外,具有虚函数(纯或非虚函数)的类也是多态类。
    • @Quentin:见链接。
    • @einpoklum 虚拟 base 类,i,e。我们说的是虚拟继承,完全不同的事情......
    • @einpoklum 哈哈 - 是时候玩了"Teekesselchen" 对不起德语链接,不知道这个游戏用英语怎么称呼(或者如果在盎格鲁-撒克逊圈子里玩过)。
    【解决方案3】:

    让我们把它转换成真正的 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 ——嗯,至少第一个要被覆盖的函数,实际上覆盖的函数然后隐式地是虚拟的。长期以来,即使在覆盖函数上也被认为是重复虚拟的好习惯,因为 C++11 是多余的,但是,因为 override 关键字也暗示了虚拟性......显然,在本文的示例语言中,函数总是隐式虚拟的...

    【讨论】:

      【解决方案4】:

      另一项努力:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-15
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 2013-03-08
        • 1970-01-01
        • 2010-11-14
        相关资源
        最近更新 更多