tags:

views:

399

answers:

5

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#

+10  A: 

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.

Tomek Szpakowicz
A: 

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++.

Pavel Minaev
A: 

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.

Marcin Gil
+1  A: 

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.

David Rodríguez - dribeas
A: 
  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.
Akshay