effective C++ 讀書筆記 條款36-37
來(lái)源:程序員人生 發(fā)布時(shí)間:2014-12-24 08:42:18 閱讀次數(shù):2679次
條款36:絕不重新定義繼承而來(lái)的non-virtual函數(shù)
重要點(diǎn):non-virtual函數(shù)都是靜態(tài)綁定
// 1241.cpp : 定義控制臺(tái)利用程序的入口點(diǎn)。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{
public:
void func()
{
cout<<"Base::func()"<<endl;
}
};
class Derived : public Base
{
public:
void func()
{
cout<<"Derived::func()"<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Derived test;
Base* pB = &test;
Derived* pD = &test;
pB->func();//調(diào)用Base::func()
pD->func();//調(diào)用Derived::func()
/*
這里我們討論的不是關(guān)于隱藏的問(wèn)題;上面pB指向1個(gè)子類,但是調(diào)用的是父類的func()函數(shù),至于為何,由于不是虛函數(shù),沒(méi)有virtual;
要明白1點(diǎn):non-virtual函數(shù) Base::func and Derived::func都是靜態(tài)綁定的,pB被聲明為1個(gè)人 pointer-to-Base,通過(guò)pB調(diào)用的non-virtual
函數(shù)永久是Base所定義的版本,即便pB指向1個(gè)類型為它的派生類的對(duì)象。
pD 調(diào)用的是Derived的函數(shù)版本,這里也能夠說(shuō)成是隱藏,但是終究緣由是由于 靜態(tài)綁定。
1般 Derived dTest,dTest.func()這樣調(diào)用我們1般說(shuō)是由于隱藏。對(duì)對(duì)象,而我們本例子當(dāng)中對(duì)應(yīng)的是指針或援用,是由于靜態(tài)綁定!
*/
getchar();
return 0;
}
總上:任何情況下都不應(yīng)當(dāng)重新定義1個(gè)繼承而來(lái)的non-virtual函數(shù);
對(duì)1個(gè)基類來(lái)講,如果1個(gè)函數(shù)定義為非虛函數(shù),那末意味著這個(gè)函數(shù)其實(shí)不想改變,所以子類不應(yīng)當(dāng)繼承它,1個(gè)類當(dāng)中的非虛函數(shù),不變性凌駕于其特異性上。
條款37:絕不重新定義繼承而來(lái)的缺省參數(shù)值:
virtual函數(shù)是動(dòng)態(tài)綁定,缺省參數(shù)值是靜態(tài)綁定;
// 1240.cpp : 定義控制臺(tái)利用程序的入口點(diǎn)。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class Shape
{
public:
enum ShapeColor{Red,Green,Blue};
virtual void draw(ShapeColor color = Red) const = 0;
};
class Rectangle:public Shape
{
public:
virtual void draw(ShapeColor color = Green) const
{
cout<<"Rectangle"<<endl;
}
};
class Circle : public Shape
{
public:
virtual void draw(ShapeColor color) const
{
cout<<"Circle"<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Shape* ps;
Shape* pc = new Circle;
Shape* pr = new Rectangle;
pr->draw();//這里調(diào)用的是Rectangle的draw函數(shù),但是函數(shù)參數(shù)color卻是Shape父類里面的參數(shù)
/*
virtual函數(shù)是動(dòng)態(tài)綁定,而缺省參數(shù)值卻是靜態(tài)綁定。
這就出現(xiàn)了上面的 調(diào)用1個(gè)定義于子類的virtual函數(shù),同時(shí)卻使用base class為它所指定的缺省參數(shù)值。
pr的動(dòng)態(tài)類型是Rectangle*,所以調(diào)用的是Ractangle的virtual函數(shù),但是由于pr的靜態(tài)類型是Shape*,所以此
函數(shù)調(diào)用的缺省參數(shù)值卻是來(lái)自魚Shape Class.
*/
getchar();
return 0;
}
總結(jié):不要重新定義1個(gè)繼承而來(lái)的缺省參數(shù)值,由于缺省參數(shù)值是靜態(tài)綁定的,而virtual函數(shù)--你唯1應(yīng)當(dāng)覆寫的東西--卻是動(dòng)態(tài)綁定!!
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)