你能用c ++隐藏虚拟方法吗?

Aar*_*her 4 c++ visual-c++

我有一个带虚函数的基类.

virtual CString& Foo();
Run Code Online (Sandbox Code Playgroud)

我想在子类中重载这个,就像这样

CString Foo();
Run Code Online (Sandbox Code Playgroud)

有没有办法隐藏基类的虚函数?像vb.net或C#中的new关键字

Tom*_*icz 16

为什么有人会这样做?它打破了基类合同.如果您不想实现与基类具有相同接口的子类,为什么要继承?使用成分.

C++中没有C#new关键字的等价物.所以你不能取消方法的'虚拟'.

如果你真的想这样做,你可以随时:

  • 将子类中的方法重写为private.

  • 创造超载.但是重载必须具有不同的参数.

但是如果你这样做,恕我直言你的设计有问题.我希望每个C++编译器都至少捕获这两种情况作为警告.

  • 你想做这样的事情的原因是支持向后兼容性.如果基类是由第三方编写的,并且您控制子类,那么如果第三方引入的虚拟方法恰好与子类上的方法具有相同的名称和签名,则代码将被破坏.对于进一步的头部扭曲,甚至可以使用用于创建隐藏现有虚拟方法的新虚拟方法的用例 - 但由于类似的原因占用vtable中的不同插槽. (2认同)

Dav*_*eas 9

首先,坏消息是你不能用另一个仅在返回类型上有所不同的函数覆盖或隐藏虚函数.然后是另一个坏消息,C++给你足够的绳索,以你以前没想过的许多方式挂起自己,你可以获得类似的效果:

struct base {
   virtual std::string const & f() { 
      static std::string s = "virtual"; 
      return s; 
   }
};
namespace detail {
   class place_holder; // no need to define it, it is just a place holder (duh)
}
struct derived : public base {
   std::string f( place_holder* p = 0 ) { return "crooked"; }
};
int main() {
   derived d; std::cout << d.f() << std::endl; // crooked
   base& b = d; std::cout << b.f() << std::endl; // virtual
}
Run Code Online (Sandbox Code Playgroud)

诀窍在于,通过在派生类中定义具有相同名称和不同参数的方法,您实际上隐藏了基类(除非您添加using base::f派生类,但调用将是不明确的).同时,由于唯一添加的参数具有默认值,您可以不带参数调用它,编译器将为您添加默认参数.

请注意,您实际上并未从对象中删除该方法,而是将其隐藏在派生类中.如果通过指针或对基类的引用调用该方法,则虚方法仍然存在并将被调用.