多重c++;档案事业;“多重定义”;错误? 我第一次在一个项目中使用多个C++文件。两者都需要包含一个受保护的(#ifndef)头文件。然而,当我这样做时,我会得到一个多定义错误

多重c++;档案事业;“多重定义”;错误? 我第一次在一个项目中使用多个C++文件。两者都需要包含一个受保护的(#ifndef)头文件。然而,当我这样做时,我会得到一个多定义错误,c++,multiple-definition-error,C++,Multiple Definition Error,我有两个.cpp文件,一个直接调用头文件,一个间接调用(另一个包含头文件),然后两个其他头文件包含头文件 那么我需要做什么来消除错误呢 错误: obj\Debug\main.o | |在函数Z14sortLibQtyTest4BookS|中:| [PATH]\miscFuncs.h | 16 |sortLibQtyTest(Book,Book)”的多个定义 代码: 应该提到的是,这并不是唯一一个给我带来问题的函数,可能超过十个,有些函数也不是那么短和甜美。此外,多个文件中需要这些函数。如果在“代

我有两个.cpp文件,一个直接调用头文件,一个间接调用(另一个包含头文件),然后两个其他头文件包含头文件

那么我需要做什么来消除错误呢

错误:

obj\Debug\main.o | |在函数
Z14sortLibQtyTest4BookS|中:|
[PATH]\miscFuncs.h | 16 |
sortLibQtyTest(Book,Book)”的多个定义

代码:


应该提到的是,这并不是唯一一个给我带来问题的函数,可能超过十个,有些函数也不是那么短和甜美。此外,多个文件中需要这些函数。

如果在“代码”后面引用的行在头文件中,则可以:

  • inline
    添加到定义或
  • 从标题中删除函数体,并将其放入1个(且仅1个)源文件中

解决此多定义问题有两个选项:将方法标记为内联,或将定义放入.cpp文件中

1) 将方法标记为内联:

// Foo.h

inline bool foo(int i) { return i = 42; }
2) 将定义放入
.cpp
文件中:

// Foo.h

inline bool foo(int i); // declaration

// Foo.cpp
bool foo(int i) { return i = 42; } // definition
在第一种情况下,编译器是否实际内联了该方法与此无关:
inline
允许您在头文件中定义非成员函数,而不违反一个定义规则。

后缀“.cpp”和“.h”在很大程度上是惯例问题。就编译器而言,一行代码来自何处是无关紧要的。将该函数包含到.cpp文件中时,就是在该.cpp文件中实现该函数

因此,当编译器完成并要求链接器将两个cpp文件中的代码组合在一起时,它会发现一个冲突:两个具有相同名称和指纹(参数和返回)的函数。这是一个错误

您需要:

a。将实现放在一个源文件中,只需在头文件中保留一个原型声明

// .h
extern bool sortLibQtyTest(Book a, Book b);

// file1.cpp
bool sortLibQtyTest(Book a, Book b) { /* implementation */ }
b。将函数标记为内联:调用函数时,编译器将根据需要插入函数体的副本,这可能会造成浪费,但通常情况下,编译器可以找到有效的方法

inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }
inline bool sortLibQtyTest(书a、书b){返回a.getQty()
c。将函数标记为“static”,告诉编译器为包含它的每个源文件创建函数的副本,但不要将其公开给链接器。如果某些源文件包含头文件而不使用该函数,编译器必须检测并删除它-并非所有编译器/优化级别都会这样做,因此可能会造成双重浪费

static bool sortLibQtyTest(Book a, Book b) {return a.getQty() < b.getQty(); }
static bool sortLibQtyTest(Book a,Book b){返回a.getQty()
d。避免c的缺点,将其标记为静态内联

static inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }
static inline bool sortLibQtyTest(Book a,Book b){返回a.getQty()
如果该函数不是类的一部分并且在标题中定义,则它应该是内联的。标记方法
inline
,或将定义放入
.cpp
文件中。请参阅添加的信息。本来应该这么说的。这两条信息都不会改变任何东西。@David
inline
说明符不强制内联。如果它不能内联,那么它就不会。那么它在这一点上的唯一目的就是避免多个定义错误。@David您只需从这两个选项中选择一个即可。听起来第二个选项更好。@David,这取决于实现。并非所有的编译器都是相同的,同样地,如果您需要,编译器也有一些强制内联的方法。
inline
关键字本身无法做到这一点,因为它只是一个提示。@David正如我所说,我认为第二个选项,即将函数定义放在
.cpp
文件中,如果您的函数不平凡,可能会更好。但是两种解决方案都能解决这个问题。你应该在C++基础上读一本书(或者任何合适的在线资源),包括声明和定义之间的区别以及使用页眉和源文件的方法。“常用的方法”是在头文件(没有函数体)中声明内容,并在关联的源文件中定义(函数体)。对于阅读本文的任何人来说,这是最简洁、最简单的答案。为了更好地理解,请阅读其他帖子上的评论。
static inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }