博客
关于我
【C/C++基础进阶系列】C/C++ 对象模型 -- 对象语义
阅读量:353 次
发布时间:2019-03-04

本文共 1558 字,大约阅读时间需要 5 分钟。

C/C++ 对象模型 - 对象语义

1. 类对象的结构 - 对象占用的空间

在C/C++中,类对象的大小主要由非静态成员变量决定。每个类对象至少会分配一个字节来存储其起始地址,即使成员变量为空。成员函数也不占用类对象的内存空间,因为它们是与类对象无关的部分。

例如:

class A{};A a;sizeof(a) = 1 // 等同于 sizeof(A)

这里,a 是一个空类对象,占用了1个字节。

如果类中有成员变量:

class A{public: int ab;}; A a;sizeof(a) = 4 // 等同于 sizeof(A)

此时,对象 a 占用了4个字节,用于存储成员变量 ab

成员函数不影响类对象的大小,因为它们是静态的或与类无关。

结论

  • 成员变量是包含在每个对象中的,占用内存。
  • 成员函数不占用类对象内存空间。

  • 2. 类对象调用方法 - this 指针调整

    在C++中,this 指针用于指向当前对象。在多继承的情况下,编译器会自动调整 this 指针的值,以指向正确的子对象。例如:

    class A{public: void func(){}};class B{public: void func(){}};class C : public A, public B {public: void func() {}};C obj;obj.func(); // 调用A的子对象的func()

    无论调用哪个函数,this 都会指向对象的起始地址。

    示例

    class A{public: int a; A() { cout << "A::A()的this指针是:%p\n"; } void func(){}};class B{public: int b; B() { cout << "B::B()的this指针是:%p\n"; } void func(){}};class C : public A, public B {public: int c; C() { cout << "C::C()的this指针是:%p\n"; } void func(){}};C myc;// sizeof(A)=4, sizeof(B)=4, sizeof(C)=12myc.func(); // 调用A类的子对象的func()

    这里,myc 是一个C对象,继承自A和B。sizeof(C) 为12,因为它包含A和B的成员变量。


    3. 对象初始化与函数传参、返回值

    3.1 对象初始化,函数传参与函数返回对象过程简析

    在C++中,对象的初始化可能涉及构造函数(构造函数)和拷贝构造函数。当函数传递对象作为函数参数时,编译器会自动插入拷贝构造函数调用。

    例如:

    class X{public: int m_i; X(X tmpx) { m_i = tmpx.m_i; } X() { m_i = 0; }};X x0; // 只构造对象,未调用构造函数X x1 = x0; // 调用拷贝构造函数X x2(x0); // 调用拷贝构造函数

    在函数中传递对象时,编译器会自动生成临时对象并调用拷贝构造函数。

    3.2 对象初始化,函数传参与函数返回对象过程优化

    为了优化性能,可以直接构造返回对象,而不是通过拷贝。例如:

    CTempValue Double(CTempValue ts) {    return CTempValue(ts.val1 * 2, ts.val2 * 2);}

    这里,编译器会直接构造并返回临时对象,无需额外拷贝。


    参考致谢

    本文参考了《C++新经典》和《C++11/14高级编程-Boost程序库探秘》等专业书籍,内容基于实际学习和实践经验,力求准确性和易读性。如有错误,请指出。

    转载地址:http://wlmr.baihongyu.com/

    你可能感兴趣的文章
    准确率94%!Python 机器学习识别微博或推特机器人
    查看>>
    Python 元组Tuple 相对于数组List的优势
    查看>>
    Android OTA升级
    查看>>
    Android基本知识
    查看>>
    在Java中,return null 是否安全, 为什么?
    查看>>
    命令模式【Command Pattern】
    查看>>
    如何将自己写的代码编进系统
    查看>>
    数据结构有哪些
    查看>>
    OSI 7 层网络模型
    查看>>
    Spring Bean 生命周期
    查看>>
    JDK 内置线程池
    查看>>
    JVM 参数默认值查询
    查看>>
    异常的继承结构
    查看>>
    SVN 和 Git 区别
    查看>>
    JDK 内置的多线程协作工具类的使用场景
    查看>>
    redis 单线程为什么快
    查看>>
    Java 源代码到运行的过程
    查看>>
    Java 中哪些对象可以获取类对象
    查看>>
    linux 的 cp 命令如何复制不提示覆盖
    查看>>
    缓存穿透 / 缓存击穿 / 缓存雪崩 / 缓存一致性
    查看>>