在类内部或外部的函数声明

我是一个正在尝试学习C ++的JAVA开发人员,但我不知道标准函数声明的最佳做法是什么。

在课堂里:

class Clazz { public: void Fun1() { //do something } } 

或者外面:

 class Clazz { public: void Fun1(); } Clazz::Fun1(){ // Do something } 

我有一种感觉,第二个可以减less可读性

C ++是面向对象的,因为它支持面向对象的软件开发范式。

然而,与Java不同的是,C ++并不强制你将类中的函数定义分组:标准的C ++声明函数的方式是声明一个没有任何类的函数。

相反,如果您正在讨论方法声明/定义,那么标准方法是将声明放在包含文件(通常名为.h.hpp )中,并将定义放在单独的实现文件中(通常名为.cpp.cxx ) 。 我同意这确实有点烦人,需要一些重复,但这是语言的devise。

对于快速实验和单个文件项目来说,任何东西都可以工作……但对于更大的项目,这种分离是实际需要的。

注意:即使你知道Java,C ++也是一种完全不同的语言,它是一种无法通过实验学习的语言。 原因是这是一个相当复杂的语言,有很多不对称性,显然是不合逻辑的select,最重要的是,当你犯了一个错误,没有“运行时错误天使”来保存你喜欢的Java …但是有“未定义的行为守护进程“。

学习C ++的唯一合理的方法是阅读…不pipe你有多聪明,都无法猜测委员会的决定。 (实际上聪明有时甚至是一个问题,因为正确的答案是不合逻辑的,也是历史遗产的结果。)

只要选好一两本书 ,然后阅读封面封面。

第一个定义你的成员函数是一个内联函数 ,而第二个不是。 在这种情况下函数的定义驻留在头本身。

第二个实现将把函数的定义放在cpp文件中。

两者在语义上是不同的,这不仅仅是一个风格问题。

课外作业定义更好。 这样你的代码可以保持安全,如果需要的话。 头文件应该只是声明。

假设有人想使用你的代码,你可以给他.h文件和你的类的.obj文件(在编译后获得)。 他不需要.cpp文件来使用你的代码。

这样你的实现对任何人都是不可见的。

“类内”(I)方法与“类外”(O)方法相同。

但是,当一个类只用于一个文件(在.cpp文件中)时,可以使用(I)。 (O)在头文件中使用。 cpp文件总是被编译的。 头文件在使用#include“header.h”时被编译。

如果在头文件中使用(I),则每次包含#include“header.h”时都会声明函数(Fun1)。 这可能会导致多次声明相同的function。 这是很难编译,甚至可能导致错误。

正确用法示例:

File1:“Clazz.h”

 //This file sets up the class with a prototype body. class Clazz { public: void Fun1();//This is a Fun1 Prototype. }; 

File2:“Clazz.cpp”

 #include "Clazz.h" //this file gives Fun1() (prototyped in the header) a body once. void Clazz::Fun1() { //Do stuff... } 

File3:“UseClazz.cpp”

 #include "Clazz.h" //This file uses Fun1() but does not care where Fun1 was given a body. class MyClazz; MyClazz.Fun1();//This does Fun1, as prototyped in the header. 

File4:“AlsoUseClazz.cpp”

 #include "Clazz.h" //This file uses Fun1() but does not care where Fun1 was given a body. class MyClazz2; MyClazz2.Fun1();//This does Fun1, as prototyped in the header. 

File5:“DoNotUseClazzHeader.cpp”

 //here we do not include Clazz.h. So this is another scope. class Clazz { public: void Fun1() { //Do something else... } }; class MyClazz; //this is a totally different thing. MyClazz.Fun1(); //this does something else. 

成员函数可以在类定义中定义,也可以使用作用域parsing运算符::分别定义。 即使不使用内联说明符,在类定义中定义成员函数也会声明函数内联。 所以要么你可以定义Volume()函数如下:

 class Box { public: double length; double breadth; double height; double getVolume(void) { return length * breadth * height; } }; 

如果你喜欢,你可以使用范围parsing运算符::在类的外部定义相同的函数,如下所示

 double Box::getVolume(void) { return length * breadth * height; } 

在这里,唯一重要的一点是你必须在::运算符之前使用类名。 一个成员函数将在一个对象上使用一个点运算符(。)来调用,它将只处理与该对象有关的数据,如下所示:

 Box myBox; myBox.getVolume(); 

(来自: http : //www.tutorialspoint.com/cplusplus/cpp_class_member_functions.htm ),这两种方式都是合法的。

我不是一个专家,但我认为,如果你只在一个文件中只放入一个类定义,那么它并不重要。

但是如果你应用类似于内部类的东西,或者你有多个类的定义,那么第二个将很难被阅读和维护。

第一个必须放在头文件(类的声明所在的地方)。 第二个可以在任何地方,无论是标题或通常,源文件。 实际上,你可以在类声明中join一些小函数(虽然它是编译器最终决定它们是否被内联),但它们隐式地声明了内联。 但是,大多数函数在头文件中都有一个声明,在cpp文件中有一个声明,就像你的第二个例子。 不,我不明白为什么这个可读性不好。 更何况,你可以实际上分割跨越几个cpp文件的types的实现。

在类中定义的函数默认被视为内联函数。 一个简单的原因,你应该在外面定义你的function:

类的构造函数检查虚函数,并初始化一个虚指针指向适当的VTABLE或虚方法表 ,调用基类的构造函数,并初始化当前类的variables,所以它实际上做了一些工作。

内联函数用于函数不那么复杂时,避免了函数调用的开销。 (开销包括在硬件级上的跳转和分支)。如上所述,构造函数并不像串联那样简单。