Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you Hide a virtual method in c++?

Tags:

c++

visual-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#

like image 664
Aaron Fischer Avatar asked Nov 27 '22 15:11

Aaron Fischer


2 Answers

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.

like image 129
Tomek Szpakowicz Avatar answered Dec 05 '22 06:12

Tomek Szpakowicz


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.

like image 31
David Rodríguez - dribeas Avatar answered Dec 05 '22 06:12

David Rodríguez - dribeas