zoukankan      html  css  js  c++  java
  • 为什么类的定义应当写在头文件中,从而被多个源文件包含?

    比如myclass.h定义了一个类myclass(只定义类,不定义成员函数),
    file1.cpp里#include "myclass.h",编译得到file1.obj;
    file2.cpp里也#include "myclass.h",编译得到file2.obj;
    那么把file1.obj和file2.obj(和运行库)连接起来生成可执行文件的时候,为什么不会有冲突呢?2个文件都包含了myclass类的定义。

    答:

    因为这遵守“单一定义规则”(One-Definition Rule, ODR)。根据此规则, 如果对同一个类的两个定义完全相同且出现在不同编译单位,会被当作同一个定义。
    这里头文件分别被两个不同的编译单位(file1.cpp, file2.cpp)包含,满足ODR规则,会被当作同一个定义。 所以不会有冲突。
    此外,模板和inline函数也适用此规则。
    追问
    类的定义在目标文件比如file1.obj里是怎么体现的呢?它产生目标代码吗?类的定义不是变量名,也不是函数名,那么在代码段、数据段或符号表里面应该都没有条目?
    还是说,类的定义只是让编译器识别下文的这个类名?而对目标文件没有任何体现?
    回答
    细节依赖于编译器的实现。
    以g++为例,类的代码出现在包含类方法定义的编译单元,引用他的编译单元会在链接时寻找类代码。如果.h中在类定义大括号内直接定义了函数,
    那么类代码会出现在每一个include这个.h的编译单元中。 以前者为例:
    myclass.h:
    class MyClass
    {
    public: MyClass(int i);
      void add();
      int m;
    };

    myclass.cpp:
    #include "myclass.h"
    MyClass::MyClass(int i)
    {
    this->m = i;
      add();
    }
    void MyClass::add()
    {
    this->m ++;
    }
    file1.cpp:
    #include "myclass.h"
    void f1()
    {
    MyClass mc(10);
    }
    file2.cpp:
    #include "myclass.h" void f2()
    {
    MyClass mc(20);
    }
    main.cpp:
    int main()
    {
     void f1();
    void f2();
    f1();
    f2();
    }

    可见类代码在myclass.o, file1.o在类定义的帮助下,通过_ZN7MyClassC1Ei引用类方法代码。
    其它细节可以反汇编代码、看elf/pe等文件格式文档以及编译器源代码。
    所谓的编译只编译cpp文件,.h文件不参与编译,头文件的作用就是告诉编译器,
    有这个类,但是类的实现在其他位置,编译时,编译器不会去找类的实现,
    链接时编译器才会去寻找这个类的实现。
  • 相关阅读:
    Spring MVC知识梳理
    Spring知识梳理
    combination sum(I, II, III, IV)
    两个面试题
    LeetCode高频148错题记录
    Multi label 多标签分类问题(Pytorch,TensorFlow,Caffe)
    Appearance-and-Relation Networks for Video Classification论文笔记 (ARTnet)
    LeetCode-450 二叉搜索树删除一个节点
    长短时记忆网络LSTM和条件随机场crf
    最大子数组(I, II, III,IV,V)和最大子数组乘积 (动态规划)
  • 原文地址:https://www.cnblogs.com/baoxiaofei/p/4189645.html
Copyright © 2011-2022 走看看