4

我来自 .Net 背景,我开始学习 c++,我在这里的教程中看到,可以通过范围运算符定义类外函数的内容::

这是教程中给出的示例:

// classes example
#include <iostream>
using namespace std;

class CRectangle {
    int x, y;
  public:
    void set_values (int,int);
   int area () {return (x*y);}
};

void CRectangle::set_values (int a, int b) {
  x = a;
  y = b;
}

int main () {
  CRectangle rect;
  rect.set_values (3,4);
  cout << "area: " << rect.area();
  return 0;
}

我在谷歌上能找到的只是范围解析,但我想知道为什么/何时应该使用声明 likeset_values而不是类中的声明 like area。有什么优势、规则、最佳实践吗?

4

4 回答 4

2

仅当您想将函数实现放在单独的文件中时才需要这样做 - 主要是 .cpp

头文件几乎总是具有 .h 扩展名。头文件的目的是保存供其他文件使用的声明。您将主要在这里定义类的外观 - 函数的定义。如果你必须上很多课,这很有用。使用 .cpp 进入细节 - 实际实现在头文件中“定义”的功能。

如果涉及很多类,使用头文件和 cpp 文件将减少构建时间。如果您感觉非常勇敢并且想进一步减少构建时间,那么我建议您阅读有关 PIMPL 模式的信息。

您可以在此处阅读有关基本信息的更多信息

于 2013-09-15T09:25:13.793 回答
1

拆分声明和实现的主要优点是在您编写代码时,这些代码将分发给最终用户,例如库。

分发代码时,您只分发头文件和目标文件 *.o。这样你的超级花哨的密码是安全的,在 .o 文件中编译,最终用户仍然可以使用它,因为他有 .h 文件,co 链接器知道在哪里查找。

于 2013-09-15T09:41:49.620 回答
1

这确实是一个好问题,这一切都归结为编译时间。来自.NET 背景的人很难理解和之间的区别#include,例如。C# 的using声明。要记住的是:

#include指令复制粘贴包含文件的内容。

因此,如果你把实现代码放在你的头文件中,你实际上是在编译它多次,在每个#include站点一次(并且链接器必须删除重复的代码)。此外,如果您更改 cpp 文件,它会单独重新编译。如果您更改头文件,包括它的所有文件(也间接地!)将被重新编译。

所以尽可能多地放在实现(即cpp)文件中。编译器作为链接时间代码优化已经足够好,这可以防止内联的事实不再像以前那样成为问题。

但是,使用模板是不可能的,这占了您在使用 C++ 时可以看到的很长的编译时间的大部分原因。

于 2013-09-15T10:17:51.013 回答
0

关键是要分离类方法的定义、声明和实现。如果您想将它们放在不同的文件中(通常,header 包含类定义和 .cpp 类实现),或者甚至出于一致性或其他原因选择不将所有内容直接放在类主体中,这非常有用。

于 2013-09-15T09:39:27.133 回答