实验:研究C++的对象模型

题目

1、定义一个类,其中有静态数据成员、各种类型非静态数据成员(含字符指针),甚至包括引用(可选),静态和非静态成员函数(含分配空间的构造函数、析构函数)。
2、定义全局对象、main函数中局部对象、另一个被main调用的外部函数func中定义局部对象(可以是形参)、main函数中动态创建对象,每种对象至少2个。观察、分析各种对象地址。
3、输出对象中各个静态与非静态数据成员的值、地址、对象的存储空间大小等信息。由此理解对象的本质、静态数据成员是本类对象共享一份拷贝等问题。此外,应观察对齐现象。
4、(可选)输出对象的每个字节,以揭示引用的实现方法。
5、对于上述各种对象,输出静态、非静态成员函数地址,以及mainfunc等外部函数的地址,并分析。要求采用合理方法,避免编译器提出警告。

分析

1、

2、

3、

4、

5、

结果截图

Image

Image

代码

#include <iostream>
#include <cstring>
using namespace std;

class MyClass {
public:
    static int StaticInt; //静态数据成员
    int nonStaticInt; //非静态数据成员
    char* charPtr; //字符指针非静态数据成员
    int& refToInt; //引用

    //构造函数
    MyClass(int val, const char* ptr) : nonStaticInt(val), refToInt(nonStaticInt) {
        charPtr = new char[strlen(ptr)+1];
        strcpy(charPtr,ptr);
    }

    //析构函数
    ~MyClass() {
        delete[] charPtr;
    }

    //静态成员函数
    static void Staticfunc() {
        
    }

    //非静态成员函数
    void nonStaticfunc()  {
        
    }

    //输出对象中每个成员的函数
    void printMembers() const {
        cout << "StaticInt" << StaticInt << "\n"
             << "nonStaticInt: " << nonStaticInt << "\n"
             << "charPtr: " << charPtr << "\n"
             << "refToInt: " << refToInt << std::endl;
    }


    //输出对象的每个字节的成员函数
    void printObjectBytes() const {
        const unsigned char* p = reinterpret_cast<const unsigned char*>(this);
        for (size_t i = 0; i < sizeof(*this); ++i) {
            printf("%02x ", p[i]);
        }
        cout << endl;
    }
};

//初始化静态成员变量
int MyClass::StaticInt = 0;

//定义全局对象
MyClass globalobj1(10, "gloabalone");
MyClass globalobj2(20, "gloabaltwo");

//外部函数func中定义局部对象,被main调用
void func1(MyClass paramobj1) {
    MyClass localfuncobj1(30, "Local in Func one");
    //在外部函数中输出对象地址
    cout << "Address of localfuncobj1: " << &localfuncobj1 <<endl;
}
void func2(MyClass paramobj2) {
    MyClass localfuncobj2(40, "Local in Func two");
    //在外部函数中输出对象地址
    cout << "Address of localfuncobj2: " << &localfuncobj2 <<endl;
}

//main
int main() {
    //定义main函数中局部对象
    MyClass localobj1(50, "localone");
    MyClass localobj2(60, "localtwo");

    //定义main函数中动态创建对象
    MyClass* dynamicobj1 = new MyClass(70, "dynamicone");
    MyClass* dynamicobj2 = new MyClass(80, "dynamictwo");

    // 输出对象的每个字节
    cout << "输出对象的每个字节" <<endl;
    cout << "globalobj1:" << endl;
    globalobj1.printObjectBytes();
    cout << "globalobj2:" << endl;
    globalobj2.printObjectBytes();
    cout << "localobj1:" << endl;
    localobj1.printObjectBytes();
    cout << "localobj2:" << endl;
    localobj2.printObjectBytes();
    cout << "dynamicobj1: " <<endl;
    dynamicobj1->printObjectBytes();
    cout << "dynamicobj2: " <<endl;
    dynamicobj2->printObjectBytes();

    // 输出对象每个成员的值
    cout << "输出对象中每个成员的值" <<endl;
    cout << "globalobj1:" << endl;
    globalobj1.printMembers();
    cout << "globalobj2:" << endl;
    globalobj2.printMembers();
    cout << "localobj1:" << endl;
    localobj1.printMembers();
    cout << "localobj2:" << endl;
    localobj2.printMembers();
    cout << "dynamicobj1: " <<endl;
    dynamicobj1->printMembers();
    cout << "dynamicobj2: " <<endl;
    dynamicobj2->printMembers();

    //输出各种对象地址
    cout << "输出各种对象地址及对象中成员的值" << endl;
    cout << "Address of globalobj1: " << &globalobj1 <<endl; 
    cout << "Address of globalobj2: " << &globalobj2 <<endl;
    cout << "Address of localobj1: " << &localobj1 <<endl;
    cout << "Address of localobj2: " << &localobj2 <<endl;
    cout << "Address of dynamicobj1: " << &dynamicobj1 <<endl;
    cout << "Address of dynamicobj2: " << &dynamicobj2 <<endl;

    //调用外部函数
    func1(localobj1);
    func2(localobj2);

    //输出函数地址
    cout << "输出函数地址" << endl;

    //输出静态函数地址
    cout << "Address of Staticfunc: " << reinterpret_cast<void*>(&MyClass::Staticfunc) << endl;

    //定义非静态函数的成员函数指针
    void (MyClass::*nonStaticfuncptr)() = &MyClass::nonStaticfunc;
    cout << "Address of nonStaticfunc: " << reinterpret_cast<void*&>(nonStaticfuncptr) << endl;
    
    //输出main函数地址
    cout << "Address of main: " << reinterpret_cast<void*>(&main) << endl;

    //输出外部函数地址
    cout << "Address of func1: " << reinterpret_cast<void*>(&func1) << endl;
    cout << "Address of func2: " << reinterpret_cast<void*>(&func2) << endl;

    delete dynamicobj1;
    delete dynamicobj2;



    return 0;
}
转载请注明出处