关于C#:是否有一种方法可以防止方法在子类中被覆盖?

关于C#:是否有一种方法可以防止方法在子类中被覆盖?

Is there a way to prevent a method from being overridden in subclasses?

有人知道C语言中的语言功能或技术可以防止子类过度使用父类中的特定方法吗?

1
2
3
4
5
6
7
8
9
class Base {
public:
    bool someGuaranteedResult() { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

即使它不是虚拟的,也仍然允许这样做(至少在我正在使用的Metrowerks编译器中),您得到的只是关于隐藏非虚拟继承函数X的编译时警告。


当您可以将final说明符用于虚拟方法(C 11引入)时,可以执行此操作。让我引用我最喜欢的文档站点:

When used in a virtual function declaration, final specifies that the function may not be overridden by derived classes.

适用于您的示例,如下所示:

1
2
3
4
5
6
7
8
9
class Base {
public:
    virtual bool someGuaranteedResult() final { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

编译时:

1
2
3
$ g++ test.cc -std=c++11
test.cc:8:10: error: virtual function ‘virtual bool Child::someGuaranteedResult()
test.cc:3:18: error: overriding final function ‘virtual bool Base::someGuaranteedResult()

使用Microsoft编译器时,还请查看sealed关键字。


一些想法:

  • 将您的功能设为私有。
  • 不要将函数虚拟化。但这实际上并不能防止该函数被另一个定义遮盖。
  • 除此之外,我不知道一种语言功能会以某种方式锁定您的函数,从而防止它被重载并仍然可以通过指向子类的指针/引用来调用。 >

    祝你好运!


    听起来像您正在寻找的声音等同于Java语言的final关键字,该关键字防止方法被子类覆盖。

    正如这里的其他人所建议的那样,您真的无法避免。同样,这似乎是一个相当常见的问题。


    为澄清起见,你们中的大多数人都误解了他的问题。他不是在问"重写"方法,而是在问是否有防止"隐藏"的方法。简单的答案是"没有!"。

    这又是他的榜样

    父类定义一个函数:

    1
    int foo() { return 1; }

    继承父级的子类定义了相同的函数AGAIN(不可覆盖):

    1
    int foo() { return 2; }

    您可以在所有编程语言上执行此操作。没有什么可以阻止此代码编译的(编译器上的设置除外)。最好的结果是警告您隐藏了父级的方法。如果调用子类并调用foo方法,将得到2。实际上已经破坏了代码。

    这是他的要求。


    (a)我不认为使函数私有是解决方案,因为这只会对派生类隐藏基类函数。派生类可以始终定义具有相同签名的新函数。
    (b)使函数成为非虚拟函数也不是一个完整的解决方案,因为如果派生类重新定义了相同的函数,则始终可以通过编译时绑定即obj.someFunction()来调用派生类函数,其中obj是对象的实例。派生类。

    我不认为有这样做的方法。此外,我想知道您决定禁止派生类覆盖基类函数的原因。


    我正在搜索相同的内容,昨天又遇到了这个[较旧的]问题。

    今天我找到了一个整洁的c 11关键字:final。我认为这可能对下一个读者有用。

    http://en.cppreference.com/w/cpp/language/final


    我猜编译器警告您的东西正在隐藏!它实际上被覆盖了吗?

    编译器可能会警告您,但是在运行时,如果指针的类型为父类,则将调用父类方法,而不管其指向的对象的实际类型如何。

    这很有趣。尝试为您的编译器制作一个小的独立测试程序。


    a compile time warning about hiding non-virtual inherited function X.

    更改编译器设置,使其变为错误而不是警告。


    从技术上讲,您可以防止虚拟函数被覆盖。但是您将永远无法更改或添加更多内容。那无济于事。最好按常见问题Lite建议在函数前使用注释。


    在您的示例中,没有函数被覆盖。相反,它是隐藏的(这是过载的一种退化情况)。
    错误在Child类代码中。正如csmba所建议的,您所能做的就是更改编译器设置(如果可能);只要您不使用隐藏其自身功能的第三方库就可以了。


    试图防止某人在子类中使用与您的函数相同的名称与尝试防止某人使用与您在链接库中声明的相同的全局函数名称没有太大不同。

    您只能希望那些打算使用您的代码的用户,而不是其他人,会小心他们如何引用您的代码,并希望他们使用正确的指针类型或使用完全限定的范围。


    除非您将方法设为虚拟,否则子类无法覆盖它。如果要防止子类调用它,请将其设为私有。

    因此默认情况下,C会执行您想要的操作。


    如果将子类作为其父类的类型来寻址,则非虚函数将调用父类的版本。

    即:

    1
    Parent* obj = new Child();

    C方法是私有的,默认情况下不可覆盖。

    • 您不能覆盖私有方法
    • 您不能覆盖非virtual方法

    您可能是指超载吗?


    推荐阅读