开发者

Can you Hide a virtual method in c++?

I have a base class with a virtual function.

开发者_运维知识库
virtual CString& Foo();

I want to overload this in subclass like so

CString Foo();

is there a way to hide the base classes virtual function? Something like the new keyword in vb.net or C#


Why anyone would do something like that? It breaks base class contract. If you don't want to implement subclass that has the same interface as base class, why do you inherit at all? Use composition.

There is no equivalent of C# new keyword in C++. So you cannot cancel method's 'virtualness'.

If you really want to do this you can always:

  • override a method in subclass as private.

  • create overload. But the overload has to have different parameters.

But if you do this, IMHO something is wrong with your design. I wish each C++ compiler caught both of this situations at least as warnings.


First, the bad news are that you cannot override nor hide a virtual function with another function that differs only on return type. Then the other bad news, C++ gives you enough rope as to hang yourself in many ways you would not have considered before and you can get an effect that is similar:

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
}

The trick there is that by defining a method with the same name and different arguments in the derived class you are actually hiding the base class (unless you add using base::f in the derived class, but then the call would be ambiguous). At the same time, since the only added argument has a default value you can call it without arguments and the compiler will add the defaulted argument for you.

Note that you are not actually removing the method from the object, but rather hiding it in the derived class. If the method is called through a pointer or reference to the base class, the virtual method is still there and will get called.


First you can't override

virtual CString& Foo()

with

CString Foo()

as they differ with nothing more as return type - this won't compile.

If a function with signature

int foo();

is virtual in base class - functions with the same signature in derived classes will also be virtual; you don't have to specify virtual in derived classes.

For more info on virtual functions (and more!) you can peek at C++ FAQ Lite.


  1. your code will not compile. i assume you know that, thats why you asked the question here.
  2. however, your concern is simply to hide the base class virtual function. For that, create another function with some other arguments than the base class function. This will hide the base class function.


technically you can, by declaring method in derived class static:

static CString& Derived::foo()

it sounds weird, but try it - compiler will eat and produce warning. Override will be ignored, and virtual Base::foo() will be hidden and replaced with static Derived::foo().

Why would you need something like that, though?


No, not really. Even if you introduce an intermediate class to make the inherited method private, it won't help, as private virtual methods are still overridable in C++.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜