views:

99

answers:

3

Hi,

I know why I want to use private virtual functions, but how exactly can I implement them?

For example:

class Base{
[...]
private:
 virtual void func() = 0;
[...]
};

class Derived1: public Base{
  void func() 
  { //short implementation is ok here
  }
};

class Derived2: public Base{
  void func(); //long implementation elsewhere (in cpp file)
};

[...] 

void Derived2::func()
{ //long implementation 
}

The first version is ok but not always possible. Isn't the second version simply name hiding? How do you define the Base::func() of Derived2, if you cannot do it within the class declaration of Dereived2?

Thanks

+3  A: 

Polymorphism and accessibility are two separate concepts. You can always override a base class' private virtual function, but you won't be able to call the base class version from anywhere but the base class itself. Also, C++ FAQ Lite has a pretty lengthy entry on the subject.

Kristo
and my question is: how exactly?
Dane
@Kristo: You can call a private base class function if you refer to it via a derived class that changed its access mode (via `public: using Base::f;` and using `myBase->f()`).
Georg Fritzsche
@Kristo, why would you want to call the base class version if it's pure virtual anyway - the context appears to be implementing the template method, so the intention is that it will only be called by the base class itself?
Phil Nash
+4  A: 

How do you define the Base::func() of Derived2, if you cannot do it within the class declaration of Dereived2?

You don't define "Base::func() of Derived2" (whatever this might be), you define Derived2::func(). This compiles just fine for me:

#include <iostream>

class Base{
private:
 virtual void foo() = 0;
public:
  void bar() {foo();}
};

class Derived: public Base{
  void foo();
};

void Derived::foo()
{
   std::cout << "inside of 'Derived1::foo()'\n";
}

int main()
{
  Derived d;
  Base& b = d;
  b.bar();
  return 0;
}

What's your problem with it?

sbi
my problem was that i thought `Derived::foo()` would declare and define a new function of Derived (not define the `Base::foo()`). But if you define your bar() function in a more ugly way: `void bar() { ((Base*)this)->foo();}`you can see that I was mistaken - it does work and hence `Base::foo()` was defined...Thanks again everybody!`
Dane
`Derived::foo()` _does_ declare a new function, but it overrides `Base::foo()`. The cast to `Base*` within `Base::bar()` is doing nothing, since within `Base` `this` always is of the type `Base* const` anyway.
sbi
A: 

For what I understand here, you're trying to do polymorphism.

There are 4 rules that you must follow to achieve polymorphism.

  1. You must inherit from the base class.
  2. Your functions must have the same name in every class.
  3. You need the virtual keyword in front of every function, and the override keyword at the end of the child's fonctions.
  4. You have to use a pointer on the main class, and use the "new" keyword to define it as a child type.

See this awesome wiki page for code example.

Hope this is what you wanted. ^^

Yours truly,

SeargX

SeargX
#3 and #4 don't even apply to C++.
sbi
Um... yes, they do. Maybe you're not forced to use the ovveride keyword, it depends on what you want to do, but it definitly applies to C++.
SeargX
override is supported in C++ as an MS extension only (presumably because they had to implement it for C++/ CLI anyway). It is not part of standard C++
Phil Nash
Oh, okay. I didn't know that, thanks for explaining.
SeargX
@SeargX: `struct Base { virtual f() {} }; struct Derived : Base { f() {} }; int main() { Derived d; Base b.f(); }` doesn't need `virtual` in front of every function, doesn't use `override` at all, and it's working without pointers or `new` - yet it's employing polymorphism in C++.
sbi
I guess that I'll have some questions to ask my teachers about that... they didn't teach it that way, they did it as I posted and made it clear that it was required. I'm sorry if I was wrong, but that's what I've been taught. <.<
SeargX
@SeargX: Did those teacher try to teach you C++?
sbi
sbi: Yes, they did. But we always worked on either Visual Studio or Borland C++, so I guess it's not "standard" C++.
SeargX