effective C++ 讀書筆記 條款36-37
來源:程序員人生 發布時間:2014-12-24 08:42:18 閱讀次數:2668次
條款36:絕不重新定義繼承而來的non-virtual函數
重要點:non-virtual函數都是靜態綁定
// 1241.cpp : 定義控制臺利用程序的入口點。
//
#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();//調用Base::func()
pD->func();//調用Derived::func()
/*
這里我們討論的不是關于隱藏的問題;上面pB指向1個子類,但是調用的是父類的func()函數,至于為何,由于不是虛函數,沒有virtual;
要明白1點:non-virtual函數 Base::func and Derived::func都是靜態綁定的,pB被聲明為1個人 pointer-to-Base,通過pB調用的non-virtual
函數永久是Base所定義的版本,即便pB指向1個類型為它的派生類的對象。
pD 調用的是Derived的函數版本,這里也能夠說成是隱藏,但是終究緣由是由于 靜態綁定。
1般 Derived dTest,dTest.func()這樣調用我們1般說是由于隱藏。對對象,而我們本例子當中對應的是指針或援用,是由于靜態綁定!
*/
getchar();
return 0;
}
總上:任何情況下都不應當重新定義1個繼承而來的non-virtual函數;
對1個基類來講,如果1個函數定義為非虛函數,那末意味著這個函數其實不想改變,所以子類不應當繼承它,1個類當中的非虛函數,不變性凌駕于其特異性上。
條款37:絕不重新定義繼承而來的缺省參數值:
virtual函數是動態綁定,缺省參數值是靜態綁定;
// 1240.cpp : 定義控制臺利用程序的入口點。
//
#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();//這里調用的是Rectangle的draw函數,但是函數參數color卻是Shape父類里面的參數
/*
virtual函數是動態綁定,而缺省參數值卻是靜態綁定。
這就出現了上面的 調用1個定義于子類的virtual函數,同時卻使用base class為它所指定的缺省參數值。
pr的動態類型是Rectangle*,所以調用的是Ractangle的virtual函數,但是由于pr的靜態類型是Shape*,所以此
函數調用的缺省參數值卻是來自魚Shape Class.
*/
getchar();
return 0;
}
總結:不要重新定義1個繼承而來的缺省參數值,由于缺省參數值是靜態綁定的,而virtual函數--你唯1應當覆寫的東西--卻是動態綁定!!
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈