仅使用标头实现的重复符号[重复]

问题描述 投票:0回答:1

我有一个在头文件中声明和实现的 C++ 类。我选择这一点是因为由于

_GLIBCXX_DEBUG
和预编译库,人们无法轻松地在调试和发布版本之间移动。例如,如果我定义
_GLIBCXX_DEBUG
,Boost 将由于源文件中的 ABI 更改而崩溃。

仅标头实现会产生重复符号的问题。例如,在下面的类中

operator==
和非成员
swap
将产生多重定义的符号。

// Foo.hpp
namespace Bar
{
  template
  class Foo
  {
    ...
  };

  bool operator==(const Foo& a, const Foo& b) {
    ..
  }
}

namespace std
{
  template <>
  void swap(Bar::Foo& a, Bar::Foo& b)
  {
    a.swap(b);
  }
}

当声明和实现分离时,文件(Foo.hpp和Foo.cpp)编译并链接正常。

让它正确编译和链接的技巧是什么?

c++ build symbols
1个回答
11
投票
inline bool operator==(const Foo& a, const Foo& b) {
    ..
  }

成员函数是隐式内联的,只要它们是在类内部定义的。同样的事情对它们来说也是如此:如果它们可以毫不费力地放入标题中,那么您确实可以这样做。

因为函数的代码放在头文件中并且可见,所以编译器能够对它们进行内联调用,即将函数的代码直接放在调用处(不是因为你在它前面放了内联,而是更多是因为编译器决定这样做,不过,仅内联是对编译器的一个提示)。这可以提高性能,因为编译器现在可以看到参数在哪里与函数的本地变量匹配,以及参数在哪里不会互相别名 - 最后但并非最不重要的一点是,不再需要函数框架分配。

© www.soinside.com 2019 - 2024. All rights reserved.