• Effective C++ 规则31:将文件间的编译依存关系降至最低


            对于下面的代码:

    1. #include
    2. #include "date.h"
    3. #include "address.h"
    4. class Person {
    5. public:
    6. Person(const std::string& name, const Date& birthday, const Address& addr);
    7. std::string name() const;
    8. std::string birthDate() const;
    9. std::string address() const;
    10. //...
    11. private:
    12. /*成员变量*/
    13. std::string m_Name;
    14. Date m_BirthDate;
    15. Address m_Address;
    16. };

            如果有很多文件使用到了Person对象,如果Date类中的实现做了修改,那么所有的文件都需要被重新编译。是因为Person类的三个成员变量既不是指针也不是引用,所以编译器在编译这个文件时必须访问这三个类型的定义式,否则无法得知该给这三个变量分配多少内存。也就是说,如果你修改了Date或Address的定义,然后重新编译,Person类所在的文件和使用Person对象的文件也不得不重新编译。

            但是如果对Person类做如下修改,就不会导致重新编译:

    1. #include
    2. class Date;
    3. class Address;
    4. class Person {
    5. public:
    6. Person(const std::string& name, const Date& birthday, const Address& addr);
    7. std::string name() const;
    8. std::string birthDate() const;
    9. std::string address() const;
    10. //...
    11. private:
    12. /*成员变量*/
    13. std::string* m_Name;
    14. Date* m_BirthDate;
    15. Address* m_Address;
    16. };

            因为编译器为指针分配的字节大小是固定的,因此不需要知道Date类和Address类的具体实现。

            因此尽量用指针和引用代替Object;尽量用class声明代替class定义式。在函数声明中,即使用到某个class,并不需要访问定义式,即使是使用by value的方式传参。

            下面的代码,把Person的具体实现都放在PersonImpl中,这样当Date等类的实现发生改变时,不需要重新编译Person文件,只需要重新编译Personimpl即可,这样可以做到解耦合。        

    1. #include
    2. #include
    3. class PersonImpl;
    4. class Date;
    5. class Address;
    6. class Person {
    7. public:
    8. Person( const std::string& name,const Date& birthday,const Address& addr);
    9. std::string name() const;
    10. std::string birthDate() const;
    11. std::address() const;
    12. ...
    13. private:
    14. std::tr1::shared_ptr pImpl;
    15. };

            还可以使用纯虚函数的方法降低文件之间的依赖,这里不再赘述。

  • 相关阅读:
    秋招华为架构分享,深谙面试之道的Java面试八股文
    Qt下使用OpenCV的鼠标回调函数进行圆形/矩形/多边形的绘制
    Android中Gradle的使用
    数据结构试题(三)
    关于unordered_map中元素的插入顺序与遍历顺序问题
    JMeter websocket接口测试
    springboot基于微信小程序的校园体育运动场地及器材租凭系统设计与实现毕业设计源码131052
    【概率论与数理统计(研究生课程)】知识点总结6(抽样分布)
    如何评价GPT-4o?
    【牛客-剑指offer-数据结构篇】【图解】JZ18 删除链表的节点 Java实现
  • 原文地址:https://blog.csdn.net/xiaoan08133192/article/details/127797991