//
// main.cpp
// 多態(tài)的原理,以及VPR指針
//
// Created by 扆佳梁 on 16/8/2.
// Copyright ? 2016年 Eric. All rights reserved.
//
#include <iostream>
using namespace std;
class Parent{
public:
Parent(int a = 0){
this->a = a;
// print();
}
virtual void print(){
cout<<"Parent "<<"a:"<<a<<endl;
}
void print2(){
cout<<"Parent Print2"<<endl;
}
private:
int a;
};
class Parent2{
public:
Parent2(int a = 0){
this->a = a;
print();
}
void print(){
cout<<"Parent "<<endl;
}
void print2(){
cout<<"Parent Print2"<<endl;
}
private:
int a;
};
class Child:public Parent{
public:
Child(int a = 0,int b = 0){
this->b = b;
// print();
}
void print(){
cout<<"child"<<"b:"<<b<<endl;
}
private:
int b;
int a;
};
void playGround(Parent *base){
base->print();
/*
C++的多態(tài)并不是通過(guò)判斷是不是父類,還是子類,決定的.
父類對(duì)象和子類對(duì)象分部有vptr 指針, 通過(guò)指針查找對(duì)應(yīng)的虛函數(shù)表,找到虛函數(shù)的入口.
這里是遲綁定,也就是在運(yùn)行時(shí)去判斷的.
*/
}
int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "Hello, World!\n";
//第一步測(cè)試 動(dòng)態(tài)原理,引出 vptr 指針.
Parent p1;
Child c1;
// playGround(&p1);
// playGround(&c1);
//第二步 打印對(duì)象的內(nèi)部大小,證明指針存在
cout<<"sizeof(Parent):"<<sizeof(Parent)<<" sizeof(Parent2):"<<sizeof(Parent2)<<endl;
//測(cè)試在64位機(jī) vpr指針占 12個(gè)字節(jié).和虛擬函數(shù)的個(gè)數(shù)無(wú)關(guān)
/**
* 第三步 測(cè)試在 構(gòu)造函數(shù)中 調(diào)用虛函數(shù)
對(duì)象在創(chuàng)建的時(shí),由編譯器對(duì)VPTR指針進(jìn)行初始化
只有當(dāng)對(duì)象的構(gòu)造完全結(jié)束后VPTR的指向才最終確定
父類對(duì)象的VPTR指向父類虛函數(shù)表
子類對(duì)象的VPTR指向子類虛函數(shù)表
總結(jié)在父類的構(gòu)造函數(shù)調(diào)用的是父類的虛函數(shù),在子類的構(gòu)造函數(shù)中調(diào)用的是子類的虛函數(shù).
*/
/**
* 第四步
*/
cout<<"分割線----------"<<endl;
Parent *pP = NULL;
Child *pC = NULL;
Child array[] = {Child(1,2),Child(2,3),Child(3,4)};
pP = array;
pC = array;
pP->print();
pC->print();
pP++;
pC++;
pP->print();
pC->print();
pP++;
pC++;
pP->print();
pC->print();
//測(cè)試 發(fā)現(xiàn) 父類和子類的 大小不一樣,就是屬性變量不同的(這里如果子類沒(méi)有int a屬性)就會(huì) 宕掉
//去掉 子類中的int a屬性 則會(huì)調(diào)用成功. 在數(shù)組中一個(gè)子類對(duì)象 去進(jìn)行增加,進(jìn)行獲取下一個(gè)元素,會(huì)由于地址增加大小不一,導(dǎo)致失敗.
//如題步長(zhǎng) 看下圖:
return 0;
}

ObjectDiagram2.png