我习惯于C,其中头文件通常只包含声明而不是定义,但C ++似乎鼓励两者混合,至少与类混合。拿这个类声明,可以很容易地放在头文件中。它的一些方法是内联定义的,不是在“内联”关键字的意义上,而是在类声明本身中内联。特别是构造函数和四个getter / setter。
MyClass.h:
class MyClass {
public:
MyClass(int a = 0, int b = 1) : _a(a), _b(b) {};
int getA() { return _a; };
int getB() { return _b; };
void setA(int a) { _a = a; };
void setB(int b) { _b = b; };
void doSomething(); // no definition here; defined in source file
void doSomething2(); // no definition here; defined in source file
void doSomething3(); // no definition here; defined in source file
private:
int _a;
int _b;
};
这是不好的形式,我应该在源文件中单独定义类的方法,只在类声明中留下方法声明,还是完全可以接受?
答案 0 :(得分:7)
可能是糟糕的形式,取决于使用标题的应用程序的“更大图片”。通过将实现放入头中,当实现发生更改时,您需要修改头...这样的修改会触发/要求使用许多构建系统重新编译客户端对象(例如make
)。相比之下,外部更改可能需要重新链接,并且当使用共享库时,可以在不对客户端应用程序进行任何更改的情况下替换这些库。因此,当没有特别的理由使用内联时,许多应用程序共享的低级标头往往更喜欢脱机实现。当预期实施需要改变时尤其如此。
有些人更喜欢分离实施的另一个原因是避免将阅读API作为一种文档形式的人混淆。当阅读量较少时,它通常更清晰,尽管有时实现有助于理解功能。但是,看到实现的程序员倾向于考虑行为/性能影响并构建依赖于它的客户端代码,即使接口没有做出严格的保证:如果实现发生变化,这会使客户端代码变得脆弱。
答案 1 :(得分:5)
它不仅可以接受,而且与将方法定义放在.cpp
文件中完全不同。 class
块中定义的方法隐式inline
。
这些天inline
并不是对编译器的强烈暗示,但它确实有所作为。特别是在调用站点上编译器可以使用的那些函数定义可以启用内联,这对于setter / getter来说通常会提高可执行文件的速度和大小。
不将方法定义放在class
块之外的头文件中,除非您明确标记它们inline
。
一个挑剔的人:你不应该用下划线开始标识符。你没有任何保留标识符,但避免初始下划线是一个好习惯。
答案 2 :(得分:3)
不,这是完全可以接受的,在内联函数或模板的情况下,有时几乎是必要的。
我喜欢它,因为人们在所有类声明之后在其内部函数的单独部分中放置了大于一行的函数。但大多数人甚至都不这样做。