c++实现友元/内联函数

发布于 2024-11-30 19:19:45 字数 627 浏览 0 评论 0原文

我似乎找不到这个新手问题的答案。如果我有课 // 头文件 (.h)

Class X {
public:
  friend bool operator==(const X&, const X&);
  inline size_type rows() const;
};

等... 当我去实现X的.cpp文件时,我应该包含inline &这几个词吗? .cpp 文件中函数名称中的friend。即,我应该实现类似于下面的文件

// CPP file (.cpp)
#include "X.h"
friend bool operator==(const X&, const X&) {
  //implementation goes here
  //return true/false
}

inline size_type rows() const {
  return r;
}

,还是应该不包含这些文件,如下所示

#include "X.h"
bool operator==(const X&, const X&) { ... }

size_type rows() const { ... }

I can't seem to find the answer to this newbie question. If I have a class
// Header file (.h)

Class X {
public:
  friend bool operator==(const X&, const X&);
  inline size_type rows() const;
};

etc...
when I go to implement the .cpp file of X, should I include the words inline & friend in the function names in the .cpp file. ie, should I implement my file similar to the below

// CPP file (.cpp)
#include "X.h"
friend bool operator==(const X&, const X&) {
  //implementation goes here
  //return true/false
}

inline size_type rows() const {
  return r;
}

or should I not include these i.e. like below

#include "X.h"
bool operator==(const X&, const X&) { ... }

size_type rows() const { ... }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只为守护你 2024-12-07 19:19:45

不,你不应该,即第二个版本是正确的。

friend 只能在类定义内使用(在类定义之外没有任何意义),编译器会通过函数签名来查找声明的 friend 函数的定义在您的类 X 中。

inline 用于头文件中(尽管,我猜,从技术上讲,也可以在 cpp 文件中使用它,只是它在那里没有意义)。请注意,仅当您实际在此处定义函数时,内联才有意义 - 如果您在 cpp 文件中单独提供函数定义,则它不会产生任何效果。

inline 的要点是提示编译器可以内联相关函数(但这并不能保证 - 编译器可以自由决定是否内联该函数)。如果函数是内联的,则对它的任何调用都将替换为函数体的副本。实际上,这样做总是为了提高性能,节省函数调用的成本,但代价是可能会增加程序大小。现在,如果我们想要内联一个函数,我们希望它在整个地方内联,而不仅仅是在单个编译单元内;这就是为什么在实现文件中使用 inline 关键字没有什么意义。

No, you shouldn't, i.e. the 2nd version is correct.

friend can only be used within a class definition (it has no meaning outside of it), and the compiler looks for the function signature to find the definition of the friend function declared within your class X.

inline is used in header files (although, I guess, technically it is possible to use it in a cpp file too, just it makes no sense there). And note that inline makes sense only if you actually define the function right there - it can have no effect if you provide the function definition separately, in a cpp file.

The point of inline is to hint the compiler that the function in question can be inlined (it is no guarantee, though - the compiler is free to decide whether it inlines that function or not). If the function is inlined, any calls to it are replaced by a copy of the function body. This is practically always done for performance benefits, to save the costs of function calls, at the expense of potentially increasing program size. Now, if we want to inline a function, we want it to be inlined all over the place, not only within a single compilation unit; this is why it makes little sense to use the inline keyword inside an implementation file.

神也荒唐 2024-12-07 19:19:45

定义 friend 函数时,您可以使用两个不同选项之一:

在类定义中定义 friend 函数

namespace Test {
class test {
   int priv;
   friend void foo( test const & t ) { std::cout << t.priv << std::endl; }
};
}

在封闭的命名空间中定义它们:

namespace Test {
class test {
   int priv;
   friend void foo( test const & t );
};
void foo( test const & t ) {
   std::cout << t.priv << std::endl;
}
}

但请注意,在查找方面存在差异。特别是,第一种情况更具限制性(因此应该是首选),因为只有 ADL(参数相关——又名 Koening——查找)才能找到它,而在第二种情况下,只要考虑该命名空间,就会考虑该函数。

也就是说,为了让编译器将第一个函数视为重载,调用处的参数必须测试,而在第二种情况下,它将被视为重载每当标识符匹配时,如果参数可转换test,则可能被视为有效选项。

When defining friend functions you can use one of two different options:

Define the friend function inside the class definition

namespace Test {
class test {
   int priv;
   friend void foo( test const & t ) { std::cout << t.priv << std::endl; }
};
}

Define them in the enclosing namespace:

namespace Test {
class test {
   int priv;
   friend void foo( test const & t );
};
void foo( test const & t ) {
   std::cout << t.priv << std::endl;
}
}

But note that there are differences regarding lookup. In particular, the first case is more restrictive (and thus should be preferred) as only ADL (Argument Dependent --aka Koening-- Lookup) will find it, while in the second case the function will be considered whenever that namespace is considered.

That is, for the compiler to consider the first function as an overload, the argument at the place of call must be a test, while in the second case it will be considered whenever the identifier matches, and might be considered as a valid option if the argument is convertible to test.

后来的我们 2024-12-07 19:19:45

您不需要函数主体上的朋友前缀,而只需要标头中的签名。

You don't want the friend prefix on the function body, just the signature in the header.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文