Qt/C++重写函数而不进行子类化

Qt/C++ Override function without subclassing

本文关键字:子类 C++ 重写 函数 Qt      更新时间:2023-10-16

我想覆盖QWidget的一个虚拟函数,而不需要对其进行子类化。这在java中是可能的。我发现了这个链接:

在Java 中重写方法而不进行子类化

不确定c++中是否也有方法。有什么想法吗?

没有继承就不能重写。链接示例中的代码确实是子类。也许混淆是因为它没有使用extends关键字。它创建了XStream的一个匿名子类,并覆盖了它的方法。C++中也存在这样的类,类似的代码也是可能的。命名约定有点不同。没有名称但有命名实例的类称为未命名。以下是我对代码的音译,以展示如何使用C++中的未命名类来完成该示例:

class SomeClass {
public:
    void myMethod() {
        class: public XStream {
        protected:
            MapperWrapper wrapMapper(const MapperWrapper& next) override {
                return MapperWrapper(next); // the example is cut off here, persumably it's creating another nested anonymous class, but i'll keep this simple
            }
        } xstream;
    }
};

您可以用QWidget替换XStream,如果您想以这种方式覆盖它,可以用它的一个虚拟类替换wrapMapper

在Java中,匿名类经常用于回调。但在C++中,我们有函数指针和最近的lambdas,这可能就是为什么与Java相比,C++代码中很少使用未命名类的原因。此外,在c++11之前,不允许将未命名类作为模板参数,因此它们对于回调函子来说是一个糟糕的选择。

在c++中,匿名类(或结构)也将是没有命名实例的类。它可以是另一个外部类的成员,并且匿名类的成员将被带到父类的命名空间中。除了,标准不允许使用匿名类。那么,这样的东西怎么可能有一个定义呢?嗯,匿名联合是允许的,匿名类与它们类似。C11标准允许匿名结构。

您的Java示例是一个子类——它只是一个匿名子类。@Override关键字只是一个诊断辅助:如果方法没有覆盖超类,它会发出错误。删除@Override对生成的代码没有任何影响。C++11也有——请参阅此链接。

在C++和Java中一样,如果不声明子类,就不能覆盖虚拟函数。如果你想有效地使用Qt,你必须习惯它!