Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在main中包含cpp文件时发生编译错误:内联函数与非内联函数_C++_Compilation_Linker_Inline_Redefinition - Fatal编程技术网

C++ 在main中包含cpp文件时发生编译错误:内联函数与非内联函数

C++ 在main中包含cpp文件时发生编译错误:内联函数与非内联函数,c++,compilation,linker,inline,redefinition,C++,Compilation,Linker,Inline,Redefinition,我有一个概念上的疑问,我将试着用一个例子来解释: main.cpp #include "array_list.cpp" int main() { array_list list1; return 0; } 场景1: 数组_list.cpp-> class array_list { private: int list[10]; public: array_list () {}; ~array_list () {}; void set_elemen

我有一个概念上的疑问,我将试着用一个例子来解释:

main.cpp

#include "array_list.cpp"
int main() 
{
  array_list list1;
  return 0;
}
场景1: 数组_list.cpp->

class array_list
{
    private:
    int list[10];
public:
    array_list () {};
    ~array_list () {};
    void set_element (int,int);

};

void array_list::set_element (int i,int a) {
list[i] = a;
}
class array_list
{
private:
    int list[10];
public:
    array_list () {};
    ~array_list () {};
    void set_element (int i,int a) {
        list[i] = a;
    }
};
错误:

main.obj:错误LNK2005:“public:void _thiscall数组_列表::set_元素(int,int)”(?set_element@array_list@@QAEXHH@Z)已在数组_list.obj中定义 1> C:\Users\vrastog\Documents\Visual Studio 2012\Projects\C++learning\Debug\list using arrays.exe:致命错误LNK1169:找到一个或多个多重定义符号

情景2: 数组_list.cpp->

class array_list
{
    private:
    int list[10];
public:
    array_list () {};
    ~array_list () {};
    void set_element (int,int);

};

void array_list::set_element (int i,int a) {
list[i] = a;
}
class array_list
{
private:
    int list[10];
public:
    array_list () {};
    ~array_list () {};
    void set_element (int i,int a) {
        list[i] = a;
    }
};
错误:没有错误

问题:我理解错误的原因。同一方法定义了两次,一次在main.obj中,第二次在array_list.obj中,因此,它应该是一个错误。
我的问题是,为什么第二种方案有效?在这里,由于我们在主文件中包含了array_list.cpp,“set_element”也应该在这里定义两次。我在这里遗漏了什么?

类定义中使方法内联,因此不会在对象文件中导致多定义错误


inline
方法应该在使用它的每个翻译单元中实现,因此
inline
方法编译成两个目标文件

C++标准草案(n3797)3.2.4:应在使用odr的每个翻译单元中定义内联函数

此外,3.2.6要求这些功能应完全相同

g++
使用弱符号实现此功能:内联函数是特殊的导出函数,在链接时不会导致多定义错误

在Linux下使用类似于
nm
的工具,自己看看。它向对象文件中发出弱符号:

$ nm arraylist.o
00000000 W _ZN10array_list11set_elementEii
(... ctors, dtors ...)
00000000 T main

此外,如果不使用该函数,或编译器内联所有引用,则可能会对其进行优化。

类定义中的方法会内联,因此不会在对象文件中导致多定义错误


inline
方法应该在使用它的每个翻译单元中实现,因此
inline
方法编译成两个目标文件

C++标准草案(n3797)3.2.4:应在使用odr的每个翻译单元中定义内联函数

此外,3.2.6要求这些功能应完全相同

g++
使用弱符号实现此功能:内联函数是特殊的导出函数,在链接时不会导致多定义错误

在Linux下使用类似于
nm
的工具,自己看看。它向对象文件中发出弱符号:

$ nm arraylist.o
00000000 W _ZN10array_list11set_elementEii
(... ctors, dtors ...)
00000000 T main

此外,如果不使用该函数,或编译器内联所有引用,它可能会得到优化。

请不要包含
.cpp
文件

在第一个示例中,函数是在类外定义的,您需要添加
内联
,否则它是一个多定义


在第二个示例中,函数是在类定义中定义的,因此它是一个隐式内联函数(就像编译器为您添加了
内联
),这就是为什么它不会导致多个定义。

请不要包含
.cpp
文件

在第一个示例中,函数是在类外定义的,您需要添加
内联
,否则它是一个多定义


在第二个示例中,函数是在类定义中定义的,因此它是一个隐式内联函数(就像编译器为您添加了
内联
),这就是为什么它不会导致多个定义。

为什么您要包含
.cpp
文件?!?这些不是要包含在内的,而是单独编译并最终链接起来的。我知道这不应该作为一个好的编码实践包含在内。但理论上这是可能的。我想通过这个例子来理解潜在的编译问题。这个问题的可能重复本质上是问为什么内联函数可以被定义多次。@Drew:完全是的!!你到底为什么要包括一个
.cpp
文件?!?这些不是要包含在内的,而是单独编译并最终链接起来的。我知道这不应该作为一个好的编码实践包含在内。但理论上这是可能的。我想通过这个例子来理解潜在的编译问题。这个问题的可能重复本质上是问为什么内联函数可以被定义多次。@Drew:完全是的!!你的意思是它不在main.obj或array_list.obj或两者中?如果它没有进入任何obj文件,那么内联方法在哪里编译?@user267096我已经扩展(并更正)了答案,包含了你问题的答案。谢谢你的回答。基本上消除了我的疑虑。作为一个扩展,内联函数在使用它的每个转换单元中都应该有定义的原因是什么?@tyl3rdurd3n如果您看到函数的定义,您可以进行内联。如果在翻译单元中看不到函数的定义,编译器所能做的就是生成一个函数调用。你的意思是它不在main.obj或array_list.obj或两者中?如果它没有进入任何obj文件,那么内联方法在哪里编译?@user267096我已经扩展(并更正)了答案,包含了你问题的答案。谢谢你的回答。基本上消除了我的疑虑。作为一个扩展,内联函数在使用它的每个转换单元中都应该有定义的原因是什么?@tyl3rdurd3n如果您看到函数的定义,您可以进行内联。如果在翻译单元中看不到函数的定义,编译器所能做的就是生成函数调用。