我完全混淆在哪里放置例如构造函数的定义.有时你会看到类似的东西
// point.h
class Point {
Point(int x, int y) {
x_ = x;
y_ = y;
}
private:
const int x_;
const int y_;
}
Run Code Online (Sandbox Code Playgroud)
然后你有时会看到这样的事情:
// point.h
class Point {
Point(int x, int y);
private:
const int x_;
const int y_;
}
// point.cc
Point::Point(int x, int y) {
x_ = x;
y_ = y;
}
Run Code Online (Sandbox Code Playgroud)
即有时像构造函数,复制构造函数等.h在.cc文件中声明然后在文件中实现,有时它们在头文件中定义,依此类推.但在哪种情况下呢?哪个是好习惯,哪个不是?
与一些答案相反,这两种做法存在差异.
如果将实现放入类声明中,该方法将自动标记为inline.对于像包装这样的非常短的方法,这是一个可行的做法 非常有用的功能.
如果您将实现放入单独的.cc文件中,那么您可以提高可读性(正如David Titarenco已经在他的回答中所写)并减少了项目中可能的依赖性.仅在方法声明中作为引用,指针或返回值出现的类只需要在标头中使用前向声明.它们的实现细节在这里无关紧要,因此对于包含此标题的每个文件也是如此.一个例子:
// test.h
class A; // forward declaration of A
// #include "decl_of_class_A.h" // not needed here, because ...
class B {
public:
A method1(); // in these cases the forward
void method2(A* a); // declaration of A above
void method3(A& a); // is completely sufficient.
};
Run Code Online (Sandbox Code Playgroud)
// test.cc
#include "decl_of_class_A.h" // here we really need
// the complete declaration of A
// in order to be able to *use* it
A B::method1() { /*...*/ }
// ...
Run Code Online (Sandbox Code Playgroud)
现在,如果您包含test.h到另一个.cc文件并且类的声明已A更改,则只test.cc需要重新编译而不是其他.cc文件.班级宣言B没有改变.
除此之外:有些情况下你必须将实现放在标题中:如果你正在编写类或函数模板或者真的想要一个函数被声明为inline.
正如Omnifarious所评论的那样:您有时看到的附加代码肯定会被每个C++编译器拒绝.const必须在初始化列表中初始化类的成员.之后它们会保持固定状态,并且不会为您提供默认的赋值运算符.这意味着即使您使用的是初始化列表,只要您没有重载赋值运算符,您就永远无法编写类似的东西:
Point p(10, 20);
Point q(0, 0);
q = p; // no assignment operator provided ==> error!
Run Code Online (Sandbox Code Playgroud)
如果你真的需要恒定坐标,你应该写const Point p(10, 20).
| 归档时间: |
|
| 查看次数: |
266 次 |
| 最近记录: |