类内部或外部的函数声明

Function declaration inside or outside the class

本文关键字:函数 声明 外部 内部      更新时间:2023-10-16

我是一名JAVA开发人员,正在努力学习C++,但我真的不知道标准函数声明的最佳实践是什么。

在课堂上:

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

或外部:

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

我有一种感觉,第二个可能不太可读。。。

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

然而,与Java不同的是,C++并不强制您在类中对函数定义进行分组:声明函数的标准C++方法是只声明一个函数,而不声明任何类。

如果您讨论的是方法声明/定义,那么标准方法是将声明放在包含文件(通常命名为.h.hpp)中,将定义放在单独的实现文件(通常名称为.cpp.cxx)中。我同意这确实有点烦人,需要一些重复,但这就是语言的设计方式(主要概念是C++编译一次只完成一个单元:您需要被编译单元的.cpp,而只需要被编译代码使用的所有单元的.h;换句话说,类的include文件必须包含生成使用该类的代码所需的所有信息)。关于这一点有很多细节,包括编译速度、执行速度、二进制大小和二进制兼容性。

对于快速实验来说,任何东西都有效。。。但对于更大的项目来说,分离是实际需要的(即使公开一些实现细节可能是有意义的。h)。

注意:即使你知道Java,C++也是一种完全不同的语言。。。这是一种无法通过实验来学习的语言。原因是这是一种相当复杂的语言,有很多不对称和明显不合逻辑的选择,最重要的是,当你犯了一个错误时;运行时错误天使";像在Java中一样保存您。。。但取而代之的是";未定义的行为守护程序";。

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

只要挑选一两本好书,把它们从头到尾读一遍就行了。

第一个将成员函数定义为内联函数,而第二个则不定义。在这种情况下,函数的定义位于标头本身。

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

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

函数定义在类外更好。这样,如果需要,您的代码可以保持安全。头文件应该只给出声明。

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

这样一来,其他人就看不到您的实现。

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

但是,当一个类只在一个文件(.cpp文件内部)中使用时,可以使用(I)。(O) 在头文件中时使用。始终编译cpp文件。使用#include"Header.h"时会编译头文件。

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

正确用法示例:

文件1:"Clazz.h"

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

文件2:"Clazz.cpp"

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

文件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.

文件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. 

文件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. 

成员函数可以在类定义中定义,也可以使用范围解析运算符:单独定义。在类定义中定义成员函数会以内联方式声明函数,即使不使用内联说明符也是如此。因此,您可以定义Volume()函数如下:

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

如果您喜欢,您可以使用范围解析操作符在类外定义相同的函数,:如下

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

这里,唯一重要的一点是,您必须在::操作符之前使用类名。成员函数将使用对象上的点运算符(.)调用,它将仅按如下方式处理与该对象相关的数据:

Box myBox;           
myBox.getVolume();  

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

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

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

第一个必须放在头文件中(类声明所在的位置)。第二个可以是任何位置,可以是头文件,也可以是源文件。在实践中,您可以将小函数放在类声明中(它隐式地内联声明它们,尽管最终决定它们是否内联的是编译器)。但是,大多数函数在头中都有声明,在cpp文件中有实现,就像第二个例子中一样。不,我看不出这本书可读性会降低的原因。更不用说,您实际上可以将一个类型的实现拆分到多个cpp文件中。

在类中定义的函数默认情况下被视为内联函数。您应该在外部定义功能的一个简单原因是:

该类的构造函数检查虚拟函数并初始化一个虚拟指针以指向正确的VTABLE或虚拟方法表,调用基类构造函数并初始化当前类的变量,因此它实际上做了一些工作。

内联函数是在函数不那么复杂的情况下使用的,可以避免函数调用的开销。(开销包括硬件级别的跳转和分支。)如上所述,构造函数并不像内联那样简单。

每次调用内联函数时,它们都会粘贴在主模因代码中。当你在类外声明函数时,当你调用函数时,它来自同一个内存。这就是为什么它好多了。