C++中的虚函数(virtual function)(3)
当一个类打算被用作其它类的基类时,它的析构函数必须是虚的。考虑下面的例子:class A{public:A() { ptra_ = new char[10];}~A() { delete[] ptra_;} // 非虚析构函数private:char * ptra_;};class B: public A{public:B() { ptrb_ = new char[20];}~B() { delete[] ptrb_;}private:char * ptrb_;};void foo(){A * a = new B;delete a;} 在这个例子中,程序也许不会象你想象的那样运行,在执行delete a的时候,实际上只有A::~A()被调用了,而B类的析构函数并没有被调用!这是否有点儿可怕? 如果将上面A::~A()改为virtual,就可以保证B::~B()也在delete a的时候被调用了。因此基类的析构函数都必须是virtual的。 纯虚的析构函数并没有什么作用,是虚的就够了。通常只有在希望将一个类变成抽象类(不能实例化的类),而这个类又没有合适的函数可以被纯虚化的时候,可以使用纯虚的析构函数来达到目的。2.4 虚构造函数? 构造函数不能是虚的。三. 虚函数使用技巧 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模式为例,Creator的factoryMethod()就是虚函数,派生类override这个函数后,产生不同的Product类,被产生的Product类被基类的AnOperation()函数使用。基类的AnOperation()函数针对Product类进行操作,当然Product类一定也有多态(虚函数)。
首页 上页 | 1 | 2 | 3 | 4 | 下页 尾页 共 4 页