3.1 private的虚函数
  考虑下面的例子:

class A
{
public:
void foo() { bar();}


private:
virtual void bar() { ...}
};

class B: public A
{
private:
virtual void bar() { ...}
};

  在这个例子中,虽然bar()A类中是private的,但是仍然可以出现在派生类中,并仍然可以与public或者protected的虚函数一样产生多态的效果。并不会因为它是private的,就发生A::foo()不能访问B::bar()的情况,也不会发生B::bar()A::bar()override不起作用的情况。
  这种写法的语意是:A告诉B,你最好override我的bar()函数,但是你不要管它如何使用,也不要自己调用这个函数。


3.2 构造函数和析构函数中的虚函数调用
  一个类的虚函数在它自己的构造函数和析构函数中被调用的时候,它们就变成普通函数了,不了。也就是说不能在构造函数和析构函数中让自己多态

例如:

class A
{
public:
A() { foo();} // 在这里,无论如何都是A::foo()被调用!
~A() { foo();} // 同上
virtual void foo();
};

class B: public A
{
public:
virtual void foo();
};

void bar()
{
A * a = new B;
delete a;
}

  如果你希望delete a的时候,会导致B::foo()被调用,那么你就错了。同样,在new B的时候,A的构造函数被调用,但是在A的构造函数中,被调用的是A::foo()而不是B::foo()


3.3 多继承中的虚函数

3.4 什么时候使用虚函数
  在你设计一个基类的时候,如果发现一个函数需要在派生类里有不同的表现,那么它就应该是虚的。从设计的角度讲,出现在基类中的虚函数是接口,出现在派生类中的虚函数是接口的具体实现。通过这样的方法,就可以将对象的行为抽象化。
  以设计模式[2]Factory Method模式为例,CreatorfactoryMethod()就是虚函数,派生类override这个函数后,产生不同的Product类,被产生的Product类被基类的AnOperation()函数使用。基类的AnOperation()函数针对Product类进行操作,当然Product类一定也有多态(虚函数)。
    另外一个例子就是集合操作,假设你有一个以A类为基类的类层次,又用了一个std::vector来保存这个类层次中不同类的实例指针,那么你一定希望在对这个集合中的类进行操作的时候,不要把每个指针再cast回到它原来的类型(派生类),而是希望对他们进行同样的操作。那么就应该将这个一样的操作声明为virtual
  现实中,远不只我举的这两个例子,但是大的原则都是我前面说到的如果发现一个函数需要在派生类里有不同的表现,那么它就应该是虚的。这句话也可以反过来说:如果你发现基类提供了虚函数,那么你最好override

 

附:C++中的虚函数和纯虚函数用法

      1.虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class)。
  2.虚函数可以被直接使用,也可以被子类(sub class)重载以后以多态的形式调用,而纯虚函数必须在子类(sub class)中实现该函数才可以使用,因为纯虚函数在基类(base class
只有声明而没有定义(#add 错,可以有定义)。
  3.虚函数和纯虚函数都可以在子类(sub class)中被重载,以多态的形式被调用。
  4.虚函数和纯虚函数通常存在于抽象基类(abstract base class -ABC)之中,被继承的子类重载,目的是提供一个统一的接口。
  5.虚函数的定义形式:virtual {method body} ;纯虚函数的定义形式:virtual { } = 0; 虚函数和纯虚函数的定义中不能有static标识符,原因很简单,被static修饰的函数在编译时候要求前期bind,然而虚函数却是动态绑定(run-time bind),而且被两者修饰的函数生命周期(life recycle)也不一样。
      6.如果一个类中含有纯虚函数,那么任何试图对该类进行实例化的语句都将导致错误的产生,因为抽象基类(ABC)是不能被直接调用的。必须被子类继承重载以后,根据要求调用其子类的方法。
  以下为一个简单的虚函数和纯虚函数的使用演示,目的是抛砖引玉!

#include
//father class
class Virtualbase
{
public:
virtual void Demon()= 0; //prue virtual function
virtual void Base() {cout<<"this is farther class"}

};


//sub class
class SubVirtual :public Virtualbase
{
public:
void Demon() { cout<<" this is SubVirtual!"< void Base() {cout<<"this is subclass Base"}

};


/* instance class and sample */
void main()
{
Virtualbase* inst = new SubVirtual(); //multstate pointer
inst->Demon();
inst->Base();
// inst = new Virtualbase();
// inst->Base()
return ;
}

 

posted on 2011-05-19 11:24  maxweii  阅读(519)  评论(0编辑  收藏  举报