C++ 类内部或外部的函数声明
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9075931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Function declaration inside or outside the class
提问by JohnJohnGa
I am a JAVA developer who is trying to learn C++, but I don't really know what the best practice is for standard function declarations.
我是一名 JAVA 开发人员,正在尝试学习 C++,但我真的不知道标准函数声明的最佳实践是什么。
In the class:
在课堂里:
class Clazz
{
public:
void Fun1()
{
//do something
}
}
Or outside:
或者在外面:
class Clazz
{
public:
void Fun1();
}
Clazz::Fun1(){
// Do something
}
I have a feeling that the second one can be less readable...
我有一种感觉,第二个可能不太可读......
回答by 6502
C++ is object oriented, in the sense that it supports the object oriented paradigm for software development.
C++ 是面向对象的,因为它支持软件开发的面向对象范式。
However, differently from Java, C++ doesn't force you to group function definitions in classes: the standard C++ way for declaring a function is to just declare a function, without any class.
但是,与 Java 不同的是,C++ 不会强制您将函数定义分组到类中:声明函数的标准 C++ 方法是只声明一个函数,而没有任何类。
If instead you are talking about method declaration/definition then the standard way is to put just the declaration in an include file (normally named .h
or .hpp
) and the definition in a separate implementation file (normally named .cpp
or .cxx
). I agree this is indeed somewhat annoying and requires some duplication but it's how the language was designed.
相反,如果您正在谈论方法声明/定义,那么标准方法是将声明放在包含文件(通常命名为.h
or .hpp
)中,并将定义放在单独的实现文件中(通常命名为.cpp
or .cxx
)。我同意这确实有点烦人,需要一些重复,但这就是语言的设计方式。
For quick experiments and single file projects anything would work... but for bigger projects this separation is something that is practically required.
对于快速实验和单文件项目,任何事情都可以工作……但对于更大的项目,这种分离实际上是必需的。
Note: Even if you know Java, C++ is a completely different language... and it's a language that cannot be learned by experimenting. The reason is that it's a rather complex language with a lot of asymmetries and apparently illogical choices, and most importantly, when you make a mistake there are no "runtime error angels" to save you like in Java... but there are instead "undefined behavior daemons".
注意:即使您了解 Java,C++ 也是一种完全不同的语言……而且它是一种无法通过实验来学习的语言。原因是它是一种相当复杂的语言,有很多不对称和明显不合逻辑的选择,最重要的是,当你犯错时,没有像 Java 那样的“运行时错误天使”来拯救你......未定义的行为守护进程”。
The only reasonable way to learn C++ is by reading... no matter how smart you are there is no way you can guess what the committee decided (actually being smart is sometimes even a problem because the correct answer is illogical and a consequence of historical heritage.)
学习 C++ 唯一合理的方法是阅读……无论你多么聪明,你都无法猜测委员会的决定(实际上聪明有时甚至是一个问题,因为正确的答案是不合逻辑的,而且是历史的结果遗产。)
Just pick a good bookor two and read them cover to cover.
只需选择一两本好书,然后从头到尾阅读。
回答by Alok Save
The first defines your member function as an inline function, while the second doesn't. The definition of the function in this case resides in the header itself.
第一个将您的成员函数定义为内联函数,而第二个则没有。在这种情况下,函数的定义驻留在标头本身中。
The second implementation would place the definition of the function in the cpp file.
第二个实现将把函数的定义放在 cpp 文件中。
Both are semantically different and it is not just a matter of style.
两者在语义上是不同的,这不仅仅是风格问题。
回答by Ajit Vaze
Function definition is better outside the class. That way your code can remain safe if required. The header file should just give declarations.
函数定义在类之外更好。这样您的代码就可以在需要时保持安全。头文件应该只给出声明。
Suppose someone wants to use your code, you can just give him the .h file and the .obj file (obtained after compilation) of your class. He does not need the .cpp file to use your code.
假设有人想使用你的代码,你可以给他你的类的 .h 文件和 .obj 文件(编译后获得)。他不需要 .cpp 文件即可使用您的代码。
That way your implementation is not visible to anyone else.
这样其他人都看不到您的实现。
回答by Maarten t Hart
The "Inside the class" (I) method does the same as the "outside the class" (O) method.
“类内”(I) 方法与“类外”(O) 方法的作用相同。
However, (I) can be used when a class is only used in one file (inside a .cpp file). (O) is used when it is in a header file. cpp files are always compiled. Header files are compiled when you use #include "header.h".
但是,当一个类仅用于一个文件(在 .cpp 文件中)时,可以使用 (I)。(O) 在头文件中时使用。cpp 文件总是被编译。使用#include "header.h" 时会编译头文件。
If you use (I) in a header file, the function (Fun1) will be declared every time you include #include "header.h". This can lead to declaring the same function multiple times. This is harder to compile, and can even lead to errors.
如果在头文件中使用 (I),则每次包含 #include "header.h" 时都会声明函数 (Fun1)。这可能导致多次声明同一个函数。这更难编译,甚至可能导致错误。
Example for correct usage:
正确使用示例:
File1: "Clazz.h"
文件 1:“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"
文件 2:“Clazz.cpp”
#include "Clazz.h"
//this file gives Fun1() (prototyped in the header) a body once.
void Clazz::Fun1()
{
//Do stuff...
}
File3: "UseClazz.cpp"
文件 3:“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"
文件 4:“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"
文件 5:“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.
回答by user116541
Member functions can be defined within the class definition or separately using scope resolution operator, ::. Defining a member function within the class definition declares the function inline, even if you do not use the inline specifier. So either you can define Volume() function as below:
成员函数可以在类定义中定义,也可以使用作用域解析运算符 :: 单独定义。在类定义中定义成员函数会声明函数内联,即使您不使用内联说明符。因此,您可以定义 Volume() 函数如下:
class Box
{
public:
double length;
double breadth;
double height;
double getVolume(void)
{
return length * breadth * height;
}
};
If you like you can define same function outside the class using scope resolution operator, :: as follows
如果您愿意,可以使用作用域解析运算符在类外定义相同的函数,:: 如下
double Box::getVolume(void)
{
return length * breadth * height;
}
Here, only important point is that you would have to use class name just before :: operator. A member function will be called using a dot operator (.) on a object where it will manipulate data related to that object only as follows:
在这里,唯一重要的一点是您必须在 :: 运算符之前使用类名。将在对象上使用点运算符 (.) 调用成员函数,该对象将仅按如下方式操作与该对象相关的数据:
Box myBox;
myBox.getVolume();
(from: http://www.tutorialspoint.com/cplusplus/cpp_class_member_functions.htm) , both ways are legal.
(来自:http: //www.tutorialspoint.com/cplusplus/cpp_class_member_functions.htm),两种方式都是合法的。
I'm not an expert, but I think, if you put only one class definition in one file, then it does not really matter.
我不是专家,但我认为,如果您只在一个文件中放置一个类定义,那么这并不重要。
but if you apply something like inner class, or you have multiple class definition, the second one would be hard to read and maintained.
但是如果你应用类似内部类的东西,或者你有多个类定义,第二个将难以阅读和维护。
回答by Marius Bancila
The first one must be put in the header file (where the declaration of the class resides). The second can be anywhere, either the header or, usually, a source file. In practice you can put small functions in the class declaration (which declares them implicitly inline, though it's the compiler that ultimately decides whether they will be inlined or not). However, most functions have a declaration in the header and the implementation in a cpp file, like in your second example. And no, I don't see any reason why this would be less readable. Not to mention you could actually split the implementation for a type across several cpp files.
第一个必须放在头文件中(类的声明所在的位置)。第二个可以在任何地方,可以是头文件,也可以是通常的源文件。在实践中,您可以将小函数放在类声明中(它隐式地声明它们,尽管最终决定它们是否内联的是编译器)。但是,大多数函数在头文件中都有一个声明,在 cpp 文件中具有实现,就像在您的第二个示例中一样。不,我没有看到任何原因为什么这会降低可读性。更不用说您实际上可以将一个类型的实现拆分到多个 cpp 文件中。
回答by R Mehta
A function that is defined inside a class is by default treated as an inline function. A simple reason why you should define your function outside:
默认情况下,在类中定义的函数被视为内联函数。您应该在外部定义函数的一个简单原因:
A constructor of the class checks for virtual functions and initializes a virtual pointer to point to the proper VTABLE or the virtual method table, calls the base class constructor, and initializes variables of the current class, so it actually does some work.
类的构造函数检查虚函数并初始化一个虚指针指向正确的VTABLE或虚方法表,调用基类构造函数,并初始化当前类的变量,所以它实际上做了一些工作。
The inline functions are used when functions are not so complicated and avoids the overhead of the function call. (The overhead includes a jump and branch on the hardware level.) And as described above, the constructor is not as simple to be considered as inline.
内联函数在函数不那么复杂时使用,避免了函数调用的开销。(开销包括硬件级别的跳转和分支。)并且如上所述,构造函数并不像内联那样简单。