如果我在头文件中实现一个类会怎么样?

pet*_*zik 5 c++ header

可能重复:
C++中的内联函数

如果我在其头文件中完全实现一个类,编译器会做什么?一个典型的例子如下:

class MyException
{    
public:
    explicit MyException(const char* file, int line) file(file), line(line) {};
    const char* getFile() const { return file };
    int getLine() const { return line };
private:
    const char* const file;
    const int line;
};
Run Code Online (Sandbox Code Playgroud)

我的目的是使用这样的类:throw MyException(__FILE__, __LINE__).

我将此头文件包含在每个.cpp文件中.我想编译器将按照定义的次数编译该类,并将(相同的)机器代码包含在它生成的每个目标文件中.现在,链接器会做什么?我尝试了一个更简单的例子(没有所有那些讨厌const的东西)并且编译得很好.

会发生什么,如果不是简单的类,我在头文件中实现了一个三屏长的C函数?最后一个问题,我应该将我的例子分成.h和.cpp文件吗?

Not*_*ist 5

所有方法都将是内联方法。您可能会在整体编译上浪费一些最少的时间,但没关系。据我所知,唯一可能发生的问题是您是否有一个静态非成本成员变量。然后您必须为它分配一个存储位置(如果需要,可以放置定义和初始值)大概在 a 中.cpp,否则您将收到有关多个定义的链接器错误。

我见过只有头文件的项目,它们只有main()CPP 中的功能,但这是大量模板化的。


And*_*zos 4

类定义本身不产生任何代码。它只是向类的用户展示它是如何布局的,以便他们可以生成适当的代码来操作它。

生成代码的是类的成员函数。当您在类定义中定义成员函数时,它会为该函数提供隐式inline声明。

函数调用可以通过以下两种方式之一进行编译和链接:

(1) 可以在映像中放置最后带有 RETURN 汇编指令的功能代码的单个副本,并且可以在调用处放置 CALL 汇编指令(连同参数传递和返回值传递)以转移控制到这段代码。

或者

(2) 函数实现的完整副本可以替换调用站点的整个函数调用。

声明的函数inline是建议编译器以第二种方式执行的。此外,inline声明允许在多个翻译单元中定义函数(因此可以将其放置在共享头文件中)。为了让编译器可以选择实现第二种方法,它需要在编译时复制函数实现。如果函数实现位于外语翻译单元中,则此功能不可用。

还应该注意的是,现代编译器使用声明为内联的函数来完成复杂的事情。看:

http://gcc.gnu.org/onlinedocs/gcc/Inline.html

  • 内联函数和内联函数之间存在细微的区别。 (2认同)