很容易理解公共继承中的虚函数。那么私有或受保护继承中的虚函数有什么意义呢?
例如:
class Base {
public:
virtual void f() { cout<<"Base::f()"<<endl;}
};
class Derived: private Base {
public:
void f() { cout<<"Derived::f()"<<endl;}
};
这仍然被称为压倒一切吗?这种情况有什么用?这两个f()的关系是什么?
谢谢!
答案 0 :(得分:13)
私有继承只是一种实现技术,而不是is-a关系,正如Scott Meyers在Effective C ++中解释的那样:
class Timer {
public:
explicit Timer(int tickFrequency);
virtual void onTick() const; // automatically called for each tick
...
};
class Widget: private Timer {
private:
virtual void onTick() const; // look at Widget private data
...
};
Widget客户端不应该在Widget上调用onTick,因为它不是概念Widget界面的一部分。
答案 1 :(得分:3)
您的f()
方法仍然被覆盖。在实现Template Method设计模式时,此关系非常有用。基本上,您将在基类中实现常见的操作集。然后,这些基类操作将调用虚拟方法,如f()
。如果派生类重写f()
,则基类操作最终会调用f()
的派生版本。这允许派生类保持基本算法相同但改变行为以满足其需要。这是一个简单的例子:
#include <iostream>
using namespace std;
class Base
{
public:
virtual void f() { cout<<"Base::f()" << endl; }
protected:
void base_foo() { f(); }
};
class DerivedOne: private Base
{
public:
void f() { cout << "Derived::f()" << endl;}
void foo() { base_foo(); }
};
class DerivedTwo: private Base
{
public:
void foo() { base_foo(); }
};
int main()
{
DerivedOne d1;
d1.foo();
DerivedTwo d2;
d2.foo();
}
这是运行时的结果:
$ ./a.out
Derived::f()
Base::f()
两个派生类都调用相同的基类操作,但每个派生类的行为都不同。
答案 2 :(得分:1)
答案 3 :(得分:1)
一个例子是:
/// Thread body interface
class runnable
{
public:
virtual ~runnable() {}
virtual void run() =0;
};
/// Starts OS thread, calls p->run() in new thread
thread_id start_thread( runnable* p );
/// Has a private thread
class actor: private runnable, private noncopyable
{
private:
thread_id tid; /// private thread
public:
actor() { tid = start_thread( this ); } // here this IS-A runnable
// ...
virtual ~actor() { stop_thread( tid ); }
private:
virtual void run() { /* work */ }
};
答案 4 :(得分:1)
私有和受保护的继承允许覆盖私有/受保护的基类中的虚函数,并且声称派生的类型都不是它的基础。
受保护的继承允许派生类的派生类了解继承关系,并仍然覆盖虚函数。
私有继承Base
类中的Derived
类,破坏派生类和基类之间的所有概念关系。派生类只是根据基类实现的,仅此而已。私有继承只是一种实现技术,并且意味着所涉及的类之间没有任何关系。