实现接口类的纯虚拟方法的方法也应该被声明为虚拟的吗?

时间:2022-09-02 12:31:32

I read different opinions about this question. Let's say I have an interface class with a bunch of pure virtual methods. I implement those methods in a class that implements the interface and I do not expect to derive from the implementation.

我对这个问题的看法不同。假设我有一个接口类,其中有一些纯虚拟方法。我在实现接口的类中实现这些方法,我不希望从实现中派生。

Is there a need for declaring the methods in the implementation as virtual as well? If yes, why?

是否需要将实现中的方法声明为virtual ?如果是,为什么?

7 个解决方案

#1


9  

No - every function method declared virtual in the base class will be virtual in all derived classes.

不——基类中声明为虚的每个函数方法在所有派生类中都是虚的。

But good coding practices are telling to declare those methods virtual.

但是好的编码实践告诉我们要声明那些方法是虚拟的。

#2


7  

virtual is optional in the derived class override declaration, but for clarity I personally include it.

在派生类覆盖声明中,virtual是可选的,但为了清晰起见,我个人将它包含在内。

#3


7  

Real need - no. Once a method is declared as virtual in the base class, it stays virtual for all derived classes. But it's good to know which method is virtual and which - not, instead of checking this in the base class. Also, in most cases, you cannot be sure, if your code will be derived or not (for example, if you're developing some software for some firm). As I said, it's not a problem, as once declared as virtual, it stays virtual, but just in case .. (:

真正的需要——没有。一旦一个方法在基类中声明为virtual,那么它对所有派生类都保持virtual。但是最好知道哪个方法是虚的,哪个是虚的,而不是在基类中检查这个。此外,在大多数情况下,您不能确定您的代码是否会派生(例如,如果您正在为某些公司开发某些软件)。正如我所说,这不是一个问题,因为一旦声明为虚,它就保持虚,但以防万一。(:

#4


5  

There is no requirement to mark them virtual.

不需要对它们进行虚拟标记。

I'd start by arguing that virtual advertises to readers that you expect derived classes to override the virtual to do something useful. If you are implementing the virtual to do something, then the virtual method might have nothing to do with the kind of thing your class is: in which case marking it virtual is silly. consider:

我首先要说明的是,虚拟广告对读者来说,您期望派生类覆盖虚拟来做一些有用的事情。如果您正在实现虚拟来做一些事情,那么虚拟方法可能与您的类没有任何关系:在这种情况下,将它标记为虚拟是愚蠢的。考虑:

class CommsObject {
   virtual OnConnect();
   virtual OnRawBytesIn();
};

class XMLStream : public CommsObject {
    virtual OnConnect();
            OnRawBytesIn();
    virtual OnXMLData();
};

In that example, OnConnect is documented as virtual in both classes because it makes sense that a descendent would always want to know. OnRawBytesIn doesn't make sense to "Export" from XMLStream as it uses that to handle raw bytes, and generate parsed data - which it notifies via OnXMLData().

在这个示例中,OnConnect在两个类中都被记录为virtual,因为后代总是想知道它是有意义的。OnRawBytesIn从XMLStream“导出”是没有意义的,因为它使用它来处理原始字节并生成解析数据——它通过OnXMLData()通知这些数据。

Having done all that, I'd then argue that the maintainer of a 3rd class, looking at XMLStream, might think that it would be "safe" to create their own OnRawBytes function and expect it to work as a normal overloaded function - i.e. the base class would call the internal correct one, and the outer one would mask the internal OnRawBytes.

在完成所有这些之后,我认为第三类的维护者,看着XMLStream,可能会认为是“安全”的创建自己的OnRawBytes函数和期望它作为一个正常的重载函数——即基类会调用内部正确,和外面的人会掩盖内部OnRawBytes。

So omitting the virtual has hidden important detail from consumers of the class and made the code behave in unexpected ways.

因此,省略虚函数对类的使用者隐藏了重要的细节,并使代码以意想不到的方式运行。

So ive gone full circle: Don't try to use it as a hint about the intended purpose of a function - DO use it as a hint about the behaviour of the function: mark functions virtual consistently so downstream programmers have to read less files to know how a function is going to behave when overridden.

所以我去兜个圈子又回到原点:不要试图使用它作为提示关于函数的目的——用它作为一个提示的行为功能:马克功能虚拟始终少所以下游程序员必须读文件知道一个函数会覆盖时的行为。

#5


4  

No, it is not needed and it doesn't prevent any coding errors although many coders prefer to put it.

不,它是不需要的,而且它也不能防止任何编码错误,尽管许多编码者喜欢把它放在一起。

Once C++0x becomes mainstream you'll be able to use the override specifier instead.

一旦c++ 0x成为主流,您就可以使用重写说明符了。

#6


2  

Once 'virtual', it's virtual all the way down to the last child. Afaik, that's the feature of the c++.

一旦“虚拟”,它就一直是虚拟的,直到最后一个孩子。Afaik,这是c++的特性。

#7


1  

If you never derive from a class then there is no point making its methods virtual.

如果从不从类派生,那么将其方法设为虚函数是没有意义的。

#1


9  

No - every function method declared virtual in the base class will be virtual in all derived classes.

不——基类中声明为虚的每个函数方法在所有派生类中都是虚的。

But good coding practices are telling to declare those methods virtual.

但是好的编码实践告诉我们要声明那些方法是虚拟的。

#2


7  

virtual is optional in the derived class override declaration, but for clarity I personally include it.

在派生类覆盖声明中,virtual是可选的,但为了清晰起见,我个人将它包含在内。

#3


7  

Real need - no. Once a method is declared as virtual in the base class, it stays virtual for all derived classes. But it's good to know which method is virtual and which - not, instead of checking this in the base class. Also, in most cases, you cannot be sure, if your code will be derived or not (for example, if you're developing some software for some firm). As I said, it's not a problem, as once declared as virtual, it stays virtual, but just in case .. (:

真正的需要——没有。一旦一个方法在基类中声明为virtual,那么它对所有派生类都保持virtual。但是最好知道哪个方法是虚的,哪个是虚的,而不是在基类中检查这个。此外,在大多数情况下,您不能确定您的代码是否会派生(例如,如果您正在为某些公司开发某些软件)。正如我所说,这不是一个问题,因为一旦声明为虚,它就保持虚,但以防万一。(:

#4


5  

There is no requirement to mark them virtual.

不需要对它们进行虚拟标记。

I'd start by arguing that virtual advertises to readers that you expect derived classes to override the virtual to do something useful. If you are implementing the virtual to do something, then the virtual method might have nothing to do with the kind of thing your class is: in which case marking it virtual is silly. consider:

我首先要说明的是,虚拟广告对读者来说,您期望派生类覆盖虚拟来做一些有用的事情。如果您正在实现虚拟来做一些事情,那么虚拟方法可能与您的类没有任何关系:在这种情况下,将它标记为虚拟是愚蠢的。考虑:

class CommsObject {
   virtual OnConnect();
   virtual OnRawBytesIn();
};

class XMLStream : public CommsObject {
    virtual OnConnect();
            OnRawBytesIn();
    virtual OnXMLData();
};

In that example, OnConnect is documented as virtual in both classes because it makes sense that a descendent would always want to know. OnRawBytesIn doesn't make sense to "Export" from XMLStream as it uses that to handle raw bytes, and generate parsed data - which it notifies via OnXMLData().

在这个示例中,OnConnect在两个类中都被记录为virtual,因为后代总是想知道它是有意义的。OnRawBytesIn从XMLStream“导出”是没有意义的,因为它使用它来处理原始字节并生成解析数据——它通过OnXMLData()通知这些数据。

Having done all that, I'd then argue that the maintainer of a 3rd class, looking at XMLStream, might think that it would be "safe" to create their own OnRawBytes function and expect it to work as a normal overloaded function - i.e. the base class would call the internal correct one, and the outer one would mask the internal OnRawBytes.

在完成所有这些之后,我认为第三类的维护者,看着XMLStream,可能会认为是“安全”的创建自己的OnRawBytes函数和期望它作为一个正常的重载函数——即基类会调用内部正确,和外面的人会掩盖内部OnRawBytes。

So omitting the virtual has hidden important detail from consumers of the class and made the code behave in unexpected ways.

因此,省略虚函数对类的使用者隐藏了重要的细节,并使代码以意想不到的方式运行。

So ive gone full circle: Don't try to use it as a hint about the intended purpose of a function - DO use it as a hint about the behaviour of the function: mark functions virtual consistently so downstream programmers have to read less files to know how a function is going to behave when overridden.

所以我去兜个圈子又回到原点:不要试图使用它作为提示关于函数的目的——用它作为一个提示的行为功能:马克功能虚拟始终少所以下游程序员必须读文件知道一个函数会覆盖时的行为。

#5


4  

No, it is not needed and it doesn't prevent any coding errors although many coders prefer to put it.

不,它是不需要的,而且它也不能防止任何编码错误,尽管许多编码者喜欢把它放在一起。

Once C++0x becomes mainstream you'll be able to use the override specifier instead.

一旦c++ 0x成为主流,您就可以使用重写说明符了。

#6


2  

Once 'virtual', it's virtual all the way down to the last child. Afaik, that's the feature of the c++.

一旦“虚拟”,它就一直是虚拟的,直到最后一个孩子。Afaik,这是c++的特性。

#7


1  

If you never derive from a class then there is no point making its methods virtual.

如果从不从类派生,那么将其方法设为虚函数是没有意义的。