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修饰后表示不会修改对象得属性,可是静态成员函数不属于对象。