float compute3d(const Point3d *_this) { return sqrt( _this->x * _this->x + _this->y * _this->y + _this->z * _this->z); }
float compute3d() { return sqrt(x * x + y * y + z *z); }
C++中的虛函數的做用主要是實現了多態的機制。多態就是用父指針指向子類 對象,而後經過父類的指針調用實際子類的成員函數。ios
// virtualFunTest.cpp : 定義控制檯應用程序的入口點。 // #include "stdafx.h" #include <iostream> using namespace std; class Base { public: virtual void f() { cout<<"Base: f()"<<endl; }; virtual void g() { cout<<"Base: g()"<<endl; }; virtual void h() { cout<<"Base: h()"<<endl; }; }; class Derive1 : public Base { public: virtual void f() { cout<<"Derive1: f()"<<endl; }; virtual void g1() { cout<<"Derive1: g1()"<<endl; }; virtual void h1() { cout<<"Derive1: h1()"<<endl; }; };
void Test1() { Base b; typedef void(*Fun)(void); Fun pFun = NULL; //int*(&b) 虛函數表指針 cout<<"對象其實地址: "<<&b<<endl; cout << "虛函數表地址:" << (int*)(&b) << endl; //*(int*)(&b) 指虛函數表 (int*)*(int*)(&b)表示虛函數表的第一個內容 //能夠理解(int*)*(int*)(&b)+0 (int*)*(int*)(&b)爲數組首地址 // Invoke the first virtual function pFun = (Fun)*((int*)*(int*)(&b)+0); // Base::f() cout << "虛函數表 — 第一個函數地址:" << (int*)*(int*)(&b) << endl; pFun(); pFun= (Fun)*((int*)*(int*)(&b)+1); // Base::g() cout << "虛函數表 — 第二個函數地址:" << (int*)*(int*)(&b) + 1<< endl; pFun(); pFun=(Fun)*((int*)*(int*)(&b)+2); // Base::h() cout << "虛函數表 — 第三個函數地址:" << (int*)*(int*)(&b) + 2<< endl; pFun(); }
void Test2() { Base *p = new Derive1(); typedef void(*Fun)(void); Fun pFun = NULL; //int*(&b) 虛函數表指針 cout<<"對象其實地址: "<<p<<endl; cout << "虛函數表地址:" << (int*)p<< endl; pFun = (Fun)*((int*)*(int*)p+0); cout << "虛函數表 — 第一個函數地址:" <<(int*)*(int*)p<< endl; pFun(); pFun= (Fun)*((int*)*(int*)p+1); cout << "虛函數表 — 第二個函數地址:" <<(int*)*(int*)p+1<< endl; pFun(); pFun=(Fun)*((int*)*(int*)p+2); cout << "虛函數表 — 第三個函數地址:" << (int*)*(int*)p+2<< endl; pFun(); pFun= (Fun)*((int*)*(int*)p+3); cout << "虛函數表 — 第四個函數地址:" << (int*)*(int*)p+3<< endl; pFun(); pFun= (Fun)*((int*)*(int*)p+4); cout << "虛函數表 — 第五個函數地址:" << (int*)*(int*)p+4<< endl; pFun(); }
Test1結果/Test2結果數組
虛函數表中按照順序依次存放了類中定義的虛函數。app
因而可知,在虛函數表中,函數地址的順序爲:函數
Derive1:f() , Base:g(), Base:h(), Derive1:g1(), Derive1:h1(), 地址由低到高,個人理解是,子類在創建本身的虛函數表時,佈局
首先將父類的虛函數表內容拷貝過來,而後檢查其中的函數有沒有被覆蓋,若是有覆蓋,替換掉,而後把其餘新添加的虛函數按照順序依次添加到虛函數表中。this
此處沒有探討多重繼承的狀況。spa
C++靜態成員函數和靜態成員設計
靜態成員變量:每個對象都共享一個變量,static成員是獨立於類的任意對象而存在的;每一個static成員是與類關聯的,和該類的對象無關。3d
靜態成員函數:靜態成員函數能夠直接訪問靜態成員變量,若是要訪問非靜態成員變量的話,只能訪問某一個對象的非靜態成員變量和靜態成員函數。能夠傳一個對象的指針,引用等參數給這個靜態成員函數。指針
class Account { public: void applyint() { amount += amount * interestRate; } static double rate() { return interestRate; } static void rate(double); //sets a new rate private: std::string owner; double amount; static double interestRate; static double initRate(); }
該類時一個銀行帳戶類,不一樣的帳戶對應不一樣的客戶,可是利率是同樣的。獨立於具體客戶對象的,全部interestRate爲靜態成員。
靜態成員的訪問。經過對象,對象指針以及類名加做用域操做符在訪問。
Account ac1; Account *ac2 = &ac1; double rate; rate = ac1.rate(); rate = ac2->rate(); rate = Account::rate();
普通的成員函數訪問靜態成員時,無需做用域操做符,能夠直接訪問,好比applyinit方法。
static data member存放於程序的data segment(數據段)中
static成員函數
在類外部定義類的靜態成員函數時,無需static關鍵字,在聲明處有static便可。
static成員是類的組成部分,但不是對象的組成部分,全部是不會像static成員函數傳遞this指針的。
static成員函數不能聲明爲const。由於成員函數被const修飾後表示不會修改對象得屬性,可是靜態成員函數不屬於對象。