它在 C++ 中是否被认为是不好的形式?将包含方法定义的类声明放入头文件中?
我习惯了 C,其中头文件通常只包含声明而不包含定义,但 C++ 似乎鼓励两者的混合,至少在类中是这样。采用可以轻松放入头文件中的类声明。它的一些方法是内联定义的,不是“inline”关键字意义上的,而是内联的,就像在类声明本身中一样。特别是构造函数和四个 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;
};
这是不好的形式吗?我应该在源文件中单独定义类的方法,只在类声明中保留方法声明,还是完全可以接受?
I am used to C, where header files usually only contain declarations and not definitions, but C++ seems to encourage the mixing of both, at least with classes. Take this class declaration which could easily be put in a header file. Some of its methods are defined inline, not in the sense of the "inline" keyword, but inline as in within the class declaration itself. Specifically the constructor and four getters/setters.
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;
};
Is this bad form and should I define the class's methods separately in a source file, leaving only method declarations in the class declaration, or is this perfectly acceptable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这可能是不好的形式,具体取决于使用标头的应用程序的“大局”。通过将实现放入标头中,您需要在实现更改时修改标头...此类修改会触发/需要使用许多构建系统(例如
make
)重新编译客户端对象。相比之下,外线更改可能需要重新链接,并且当使用共享库时,可以替换这些库,而无需对客户端应用程序进行任何更改。因此,当没有特殊原因使用内联时,许多应用程序共享的低级标头往往更喜欢离线实现。当预计实施需要更改时尤其如此。有些人喜欢分离实现的另一个原因是避免人们将 API 作为文档形式进行阅读时感到困惑。当需要阅读的内容较少时,通常会更清晰,尽管有时实现有助于理解功能。但是,看到实现的程序员倾向于考虑行为/性能影响并构建依赖于此的客户端代码,即使接口没有做出严格的保证:如果实现发生变化,这会使客户端代码变得脆弱。
It may be bad form, depending on the "bigger picture" of the applications using the header. By putting implementation into the header you're requiring modifications to the header when that implementation changes... such modifications trigger/require client object recompilation with many build systems (e.g.
make
). By way of contrast, out-of-line changes may require relinking, and when shared libraries are used those libraries may be able to be replaced without any changes to the client apps. Consequently, when there's no particular reason to use inlining, low-level headers shared by many applications tend to prefer out of line implementation. This is particularly true when the implementation can be expected to need changes.Another reason some people prefer separating implementation is to avoid confusing people reading the API as a form of documentation. When there's less to read it's generally clearer, although sometimes the implementation helps in understanding the functionality. But, programmers who see the implementation tend to think about the behavioural/performance implications and build client code that depends on that, even if the interface doesn't make as strict guarantees: this makes the client code fragile should the implementation change.
它不仅是可以接受的,而且它完成的事情与将方法定义放在
.cpp
文件中略有不同。在class
块内定义的方法是隐式内联
的。如今,内联对于编译器来说并不是一个强烈的提示,但它确实有所不同。特别是让编译器在调用站点可以轻松使用这些函数定义可以启用内联,这对于 setter/getter 来说通常会提高可执行文件的速度和大小。
不要将方法定义放在
class
块之外但放在头文件内,除非您显式将它们标记为inline
。不过,有一点挑剔:标识符不应该以下划线开头。那里没有任何保留的标识符,但避免使用开头的下划线是一个好习惯。
Not only is it acceptable, it accomplishes something subtly different than putting the method definitions in the
.cpp
file. A method defined inside theclass
block is implicitlyinline
.These days
inline
isn't a strong hint to the compiler, but it does make a difference. In particular having those function definitions readily available to the compiler at the call site may enable inlining, which for setters/getters usually improves both speed and size of the executable.Do not put method definitions outside the
class
block yet inside the header file, unless you explicitly tag theminline
.A nitpick, though: you shouldn't begin identifiers with an underscore. You don't have any reserved identifiers there, but it's a good habit to avoid initial underscores.
不,这是完全可以接受的,并且在内联函数或模板的情况下有时几乎是必要的。
我喜欢人们将超过一行左右的函数放在所有类声明之后的内联函数的单独部分中。但大多数人甚至不这样做。
No, it's perfectly acceptable, and in the case of inline functions or templates sometimes almost necessary.
I like it when people put functions that are more than a line or so in their own separate section of inline functions after all the class declarations though. But most people don't even do that.