简体   繁体   English

为什么在类之外(但在头文件中)定义的类成员函数必须内联?

[英]Why do class member functions defined outside the class (but in header file) have to be inlined?

I have read existing answers on the two meanings of inline, but I am still confused.我已经阅读了有关内联两种含义的现有答案,但我仍然感到困惑。

Let's assume we have the following header file:假设我们有以下头文件:

// myclass.h

#ifndef INCLUDED_MYCLASS
#define INCLUDED_MYCLASS

class MyClass
{
   public:
      void foo(); // declaration
};

inline void MyClass::foo()
{
    // definition
}

#endif

Why does void foo() which is defined outside the class in the file, have to be explicitly defined with inline ?为什么在文件中的类之外定义的void foo()必须用inline显式定义?

It's because you defined MyClass::foo in a header file.这是因为您在头文件中定义了MyClass::foo Or a bit more abstract, that definition will be present in multiple translation units (every .cpp file that includes the header).或者更抽象一点,该定义将出现在多个翻译单元中(每个包含标题的 .cpp 文件)。

Having more than one definition of a variable/function in a program is a violation of the one definition rule, which requires that there must be only one definition in a single program of every variable/function.在一个程序中对一个变量/函数有多个定义是违反一个定义规则的,它要求在一个程序中每个变量/函数必须只有一个定义。

Note that header guards do not protect against this, as they only protect if you include the same header multiple times in the same file.请注意,标头保护不能防止这种情况发生,因为它们仅在您在同一文件中多次包含相同标头时提供保护。

Marking the function definition as inline though means that the definition will always be the same across multiple translation units.将函数定义标记为inline意味着定义在多个翻译单元中始终相同。 1 . 1 .

In practice, this means that the linker will just use the first definition of MyClass::foo and use that everywhere, while ignoring the rest,实际上,这意味着链接器将只使用MyClass::foo的第一个定义并在任何地方使用它,而忽略其余部分,


1 : If this is not the case your program is ill-formed with no diagnostics required whatsoever. 1 : 如果不是这种情况,则您的程序格式错误,不需要任何诊断。

If you put MyClass::foo() in a header file and fail to declare it inline then the compiler will generate a function body for every compilation unit that #include s the header and these will clash at link time.如果您将MyClass::foo()放在头文件中并且未能将其声明为inline那么编译器将为每个包含#include头文件的编译单元生成一个函数体,并且这些将在链接时发生冲突。 The usual error thrown by the linker is something along the lines of Multiple definition of symbol MyClass::foo() or somesuch.链接器抛出的常见错误是Multiple definition of symbol MyClass::foo()Multiple definition of symbol MyClass::foo()或类似的东西。 Declaring the function inline avoids this, and the compiler and linker have to be in cahoots about it.将函数声明为inline避免了这种情况,编译器和链接器必须对此进行协调。

As you mention in your comment, the inline keyword also acts a hint to the compiler that you'd like the function to be actually inlined, because (presumably) you call it often and care more about speed than code size.正如您在评论中提到的, inline关键字还向编译器暗示您希望函数实际内联,因为(大概)您经常调用它并且更关心速度而不是代码大小。 The compiler is not required to honour this request though, so it might generate one or more function bodies (in different compilation units) which is why the linker has to know that they are actually all the same and that it only needs to keep one of them (any one will do).编译器不需要满足这个请求,所以它可能会生成一个或多个函数体(在不同的编译单元中),这就是为什么链接器必须知道它们实际上都是相同的,并且它只需要保留其中之一他们(任何人都会做)。 If it didn't know they were all the same then it wouldn't know what to do, which is why the 'classical' behaviour has always been to throw an error.如果它不知道它们都是一样的,那么它就不知道该怎么做,这就是为什么“经典”行为总是抛出错误的原因。

Given that the compilers these days often inline small functions anyway, most compilers also have some kind of noinline keyword but that is not part of the standard.鉴于noinline编译器无论如何经常内联小函数,大多数编译器也有某种noinline关键字,但这不是标准的一部分。

More about inline at cppreference .有关cppreference inline更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么类成员函数内联? - Why are class member functions inlined? 在头文件中定义的模板类成员函数中使用名称空间 - using namespace in template class member functions defined in header file 在 C++ 中,为什么必须在类外部定义类成员函数以便单独编译? - In C++, why must class member functions be defined outside class for separate compilation? 在类的内部和外部定义的模板类的成员函数之间的差异 - Difference between member functions for a template class defined inside and outside of the class 在类主体外部定义的C ++成员函数的编译 - Compilation of C++ member functions defined outside the class body 是否在隐式内联的类中定义了静态成员函数? - Is a static member function defined inside a class implicitly inlined? 标题中定义的C ++类方法是否始终内联? - Are C++ class methods defined in the header always inlined? 为什么在CPP中“内联”一个类的析构函数,该cpp仅包含该类的头文件 - why the destructor of a class is “inlined” in a cpp which which ONLY includes the class's header file C++:在 class 主体之外定义但包含在 header 保护中的成员函数的 ODR 冲突(如 YouCompleteMe 插件中所示) - C++: ODR violation for member functions defined outside of class body but enclosed within header guard (as shown in YouCompleteMe plugin) 为什么需要在 class 之外定义 static 数据成员? - Why does a static data member need to be defined outside of the class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM