C++面向对象基础知识详解二

============================================微笑Begin微笑=====================================

接着上篇博客介绍。继续讨论分析类对象在内存中分配布局,这篇博客主要介绍有虚函数时类对象在内存中的分配和布局。

“能量补充":使用虚函数,系统要有一定的空间开销。当一个类声明了虚函数时,编译器会为该类构造一个虚函数表(

virtual function table, 简称vtalbe),它是一个指针数组,每个元素存放虚函数的入口地址。类对象本身只存放了一个指向虚函

数表的指针。


=============================================================================================

(4)带有虚函数的类对象的内存分布


#include<iostream>
#include<cstring>
using namespace std; 
class Student{
    public:
        char* _sname;
        int _sid;
    protected:
        int _sage;
    private:
        int _score;
    public:
        Student(int, char*, int, int);
        ~Student();
        virtual void Display();
        virtual void ClassType();
        virtual void FunctionStudent();
};
Student::Student(int sid, char* sname, int sage, int score)
    :_sid(sid), _sage(sage), _score(score){
        int len = strlen(sname)+1;
        this->_sname = new char[len];
        strcpy(this->_sname, sname);

}
Student::~Student(){
    delete[] this->_sname;
}
void Student::Display(){
    cout << "SID   = "<<this->_sid<<endl;
    cout << "SName = "<<this->_sname<<endl;
    cout << "SAge  = "<<this->_sage<<endl;
    cout << "Score = "<<this->_score<<endl;
}
void Student::ClassType(){
    cout << "This is Student Class"<<endl;
}
void Student::FunctionStudent(){
    cout << "Student::FunctionStudent()"<<endl;
}


int main(void){
   Student stu(100, (char*)"s_river", 22, 60); 
   Student* pstu = &stu;

   pstu->Display();
   pstu->ClassType();
   pstu->FunctionStudent();

   cout << "sizeof(Student) = " << sizeof(stu) << " sizeof(Student*) = " << sizeof(pstu) << endl; 

   return 0;
}

(5)带有虚函数继承的类对象的内存分布


class Graduate : public Student{
    private:
        int _salary;
    public:
        char* _addr;
    public:
        Graduate(int, char*, int, int,
                 int, char*);
        ~Graduate();
        virtual void Display();
        virtual void ClassType();
        virtual void FunctionGraduate();
};
Graduate::Graduate(int sid, char* sname, int sage, int score,
                   int salary, char* addr)
    :Student(sid,sname,sage, score),
    _salary(salary){
    int len = strlen(addr)+1;
    this->_addr = new char[len];
    strcpy(this->_addr, addr); 
}
Graduate::~Graduate(){
    delete[] this->_addr;
}
void Graduate::Display(){
    cout << "SID     = "<<this->_sid<<endl;
    cout << "SName   = "<<this->_sname<<endl;
    cout << "SAge    = "<<this->_sage<<endl;
    //cout << "Score = "<<this->_score<<endl;
    cout << "Salary  = " << this->_salary << endl;
    cout << "Address = " << this->_addr << endl;
}
void Graduate::ClassType(){
    cout << "This is Graduate Class" << endl;
}
void Graduate::FunctionGraduate(){
    cout << "Graduate::FunctionGraduate()" << endl;
}
int main(void){
   Student stu(100, (char*)"s_river", 22, 60); 
   Graduate grt(100, (char*)"g_s_river", 22, 60, 10001, (char*)"Wuhan");
   Student* pstu = &stu;
   Graduate* pgrt = &grt;
   pstu->Display();
   pstu->ClassType();
   pstu->FunctionStudent();
   pgrt->Display();
   pgrt->ClassType();
   pgrt->FunctionGraduate();
   cout << "sizeof(Student) = " << sizeof(stu) << " sizeof(Student*) = " << sizeof(pstu) << endl; 
   cout << "sizeof(Graduate) = " << sizeof(grt) << " sizeof(Graduate*) = "<<sizeof(pgrt) << endl;
<span style="color:#ff0000;">   pstu = &grt;</span>
   pstu->Display();
   pstu->ClassType();
   pstu->FunctionStudent();
   return 0;
}


(6)带有虚函数的多重继承类对象内存分布


class Graduate : public Student, public Teacher{
    private:
        int _salary;
    public:
        char* _addr;
    public:
        Graduate(int, char*, int, int,
                 int, char*, char*,
                 int, char*);
        ~Graduate();
        virtual void Display();
        virtual void ClassType();
        virtual void FunctionGraduate();
}; 
Graduate::Graduate(int sid, char* sname, int sage, int score,
                   int tid, char* tname, char* title,
                   int salary, char* addr)
    :Student(sid,sname,sage, score),
     Teacher(tid, tname, title),
    _salary(salary){
    int len = strlen(addr)+1;
    this->_addr = new char[len];
    strcpy(this->_addr, addr); 
}
Graduate::~Graduate(){
    delete[] this->_addr;
}
void Graduate::Display(){
    cout << "SID     = "<<this->_sid<<endl;
    cout << "SName   = "<<this->_sname<<endl;
    cout << "SAge    = "<<this->_sage<<endl;
    //cout << "Score = "<<this->_score<<endl;
    cout << "Salary  = " << this->_salary << endl;
    cout << "Address = " << this->_addr << endl;
}
void Graduate::ClassType(){
    cout << "This is Graduate Class" << endl;
}
void Graduate::FunctionGraduate(){
    cout << "Graduate::FunctionGraduate()" << endl;
}
int main(void){
   Student stu(100, (char*)"s_river", 22, 60); 
   Teacher ter(999, (char*)"t_river", (char*)"Professor");
   Graduate grt(100, (char*)"g_s_t_river", 22, 60, 999, (char*)"g_s_t_river", (char*)"Professor",10001,(char*)"Wuhan");
   Student* pstu = &stu;
   Teacher* pter = &ter;
   Graduate* pgrt = &grt;
   pstu->Display();
   pstu->ClassType();
   pstu->FunctionStudent();
   pter->Display();
   pter->ClassType();
   pter->FunctionTeacher();
   pgrt->Display();
   pgrt->ClassType();
   pgrt->FunctionGraduate();
   cout << "sizeof(Student) = " << sizeof(stu) << " sizeof(Student*) = " << sizeof(pstu) << endl; 
   cout << "sizeof(Teacher) = " << sizeof(ter) << " sizeof(Teacher*) = " << sizeof(pter) << endl;
   cout << "sizeof(Graduate) = " << sizeof(grt) << " sizeof(Graduate*) = "<<sizeof(pgrt) << endl;
   cout << "Student* pstu = &grt "<< endl;
   pstu = &grt;
   pstu->Display();
   pstu->ClassType();
   pstu->FunctionStudent();
   cout << "Teacher* pter = &grt " << endl;
   pter = &grt;
   pter->Display();
   pter->ClassType();
   pter->FunctionTeacher();
   return 0;
}


分析:子类将每个父类的虚表指针_vptr都继承下来,并指向自身的虚表,虚表的每一项都是一个虚函数的入口地址。

虚表存放虚函数入口地址的顺序是按照虚函数声明的顺序进行存储。若派生类中重写了基类中某个虚函数,那么子

类在构造虚函数表时将该虚函数在基类虚函数表中所在的位置替换成子类本身的需函数。注意:派生类将自己特有

的虚函数入口地址存储在所继承的第一个基类的虚函数表的后面。



=====================================================微笑End微笑========================================

由于知识存储有限, 以上内容若有错误或者不恰当的地方,欢迎广大网友留言指正。 微笑微笑微笑微笑微笑微笑微笑微笑


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cugriver

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值