【问题标题】:usage of virtual keyword with a class declaration在类声明中使用 virtual 关键字
【发布时间】:2009-05-06 09:50:45
【问题描述】:

我在一次采访中被问到,在 C++ 中,虚拟关键字与类声明的用法是什么,我回答说虚拟关键字不能与 C++ 中的类声明一起使用。面试官说有可能,让我以后测试一下。

现在我自己检查过了,我知道这是可能的,这不是编译器错误。事实上,当我用 Visual C++ 编译器做这样的事情时:

virtual class Test
{
   int i;
};

我收到一个编译器警告“警告 C4091:'virtual':当没有声明变量时,'Test' 左侧被忽略”。我还没有弄清楚这个警告的含义以及 virtual 关键字的用法。如果没有有用的用法,那么为什么首先允许这样做,为什么这不是编译器错误。

【问题讨论】:

    标签: c++ virtual


    【解决方案1】:

    这是 VC++ 中的一个错误。 Comeau 和 gcc 都拒绝该代码。

    【讨论】:

    • 我不知道这不适用于其他编译器。你可能是唯一一个似乎理解我的问题的人。
    • 总是值得在多个编译器上尝试。 Gcc 是免费的,您可以在 Comeau 上免费试用代码:comeaucomputing.com/tryitout
    • 阿米尔,你似乎有两个问题:(1)面试官是什么意思? (2) 为什么这是合法的语法?我想大多数人都试图回答 (1) 而不是 (2)。
    • 是的,我认为你是对的。问这个问题的时候可能我不够清楚。无论如何,我现在已经停止回复与(1)相关的答案了。
    【解决方案2】:

    virtual可以在从另一个类派生时使用:

    class Foo : public virtual Bar
    {
    }
    

    这用于避免在使用多重继承时具有相同基类的多个版本。 Wikipedia 有一篇关于这个主题的好文章。

    【讨论】:

    • 我绝对知道以这种方式使用虚拟。但是请看一下我在原始问题中给出的示例。我只想问,如果没有使用,为什么允许这样做。
    【解决方案3】:

    您根本不能将 virtual 用于类。它仅适用于成员函数

    【讨论】:

    • 它与 Microsoft Visual C++ 编译器一起工作,只生成一个警告,而不是我已经说过的错误。
    • 你可以“虚拟继承”,但我在上课之前从未见过virtual关键字
    • @Aamir:VC 编译器以及较小的 g++ 编译器对于用于验证您的代码的编译器来说是糟糕的选择。如果您想测试标准代码,请查看 Comeau 在线试用:comeaucomputing.com/tryitout
    【解决方案4】:

    您正在查看错误的用法 - 我很确定面试官指的是虚拟基类声明,如下所示:

      class A : virtual public B, public C {
        ...
      };
    

    这是一个常见的习惯用法,用于绕过菱形继承树中的“多基类”场景。它们的典型问题是您从类 B 和类 C 继承,并且它们共享共同的祖先 A。如果您“向上”继承树,您将遇到关于您是哪个“A”实例的歧义应该使用。如果 B & C 将 A 作为虚拟基类,它们将引用 A 的同一个实例,从而解决了这个问题。

    您可以使用类图here 找到更详尽的描述。

    【讨论】:

    • 正如我已经在另一条评论中回答的那样,我非常了解这种用法​​,并且我与面试官就您提到的那种用法进行了很好的讨论。但他后来想出了这个(我问过的事情)。他自己很可能不知道这一点。 :)
    【解决方案5】:

    也许他指的是虚拟继承/虚拟基类?例如

    class A : virtual public B
    { ... }
    

    从技术上讲,这将是类定义的一部分。

    【讨论】:

      【解决方案6】:

      他是不是一直在谈论在类声明中使用虚拟基类?

      像这样:

      class CashierQueue : virtual public Queue {};
      

      当您希望避免派生类从两个或多个共享相同基类的类继承时,它会在多继承中使用成员数据的多个副本。

      class Queue {};
      class CashierQueue : virtual public Queue {};
      class LunchQueue : virtual public Queue {};
      class LunchCashierQueue : public LunchQueue, public CashierQueue {};
      

      http://msdn.microsoft.com/en-us/library/wcz57btd(VS.80).aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-26
        • 2023-03-06
        • 2018-07-03
        • 1970-01-01
        相关资源
        最近更新 更多