类内外的函数声明

Joh*_*nGa 83 c++ inline

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

在课堂里:

class Clazz
{
 public:
    void Fun1()
    {
        //do something
    }
}
Run Code Online (Sandbox Code Playgroud)

或者在外面:

class Clazz
{
public:
    void Fun1();
}

Clazz::Fun1(){
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

我觉得第二个可读性较差......

650*_*502 49

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

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

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

对于快速实验和单个文件项目,任何事情都可行......但对于更大的项目,这种分离是实际需要的.

注意:即使您了解Java,C++也是一种完全不同的语言......而且它是一种无法通过实验学习的语言.原因是它是一种相当复杂的语言,有很多不对称和明显不合逻辑的选择,最重要的是,当你犯了一个错误时,没有"运行时错误天使"可以像Java一样拯救你......但是有"未定义的行为守护进程".

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

只需挑选一本好书,然后阅读封面即可.

  • 不回答这个问题 (13认同)
  • 如果有人来自Java并要求提供C++方面的帮助,那么如果你说"你所知道的语言痴迷于某些东西",它会告诉他什么?他没有与其他语言进行比较,所以这几乎没有告诉他什么.比使用像痴迷的强烈情感内涵的词更好,这并不能说明OP,你可能会考虑将这部分留下来.而且,"为每一个人使用课堂"的背景是什么?在Java中,您不使用类作为方法.您不为变量使用类.你没有为一个文件使用一个类.那么这里的"一切"是什么?咆哮? (7认同)
  • @DanielS:删除那部分因为显然冒犯了你(不明白为什么).我肯定不是在咆哮Java,因为我根本就没有使用Java,我当时只是认为OOP作为Object Obsessed Programming是一个有趣的笑话,而显然它不是.我一直是Java 1.1认证的程序员,但当时决定,除非出于某种原因被迫,我不会使用那种"编程语言",到目前为止我成功地避免了它. (2认同)
  • @PetrPeller:第三段中你不清楚的部分是什么? (2认同)

Alo*_*ave 22

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

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

两者在语义上都不同,这不仅仅是一种风格问题.

  • http://www.cplusplus.com/doc/tutorial/classes/ 给出了相同的答案:“完全在其类中定义类成员函数或仅包含原型然后再定义它的唯一区别在于,在第一种情况下,编译器会自动将函数视为内联成员函数,而在第二种情况下,它将是普通(非内联)类成员函数,实际上假设行为没有区别。” (2认同)

Aji*_*aze 15

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

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

这样,任何人都无法看到您的实施.


小智 9

"Inside the class"(I)方法与"class of class"(O)方法的作用相同.

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

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

正确使用示例:

File1:"Clazz.h"

//This file sets up the class with a prototype body. 

class Clazz
{
public:
    void Fun1();//This is a Fun1 Prototype. 
};
Run Code Online (Sandbox Code Playgroud)

File2:"Clazz.cpp"

#include "Clazz.h" 
//this file gives Fun1() (prototyped in the header) a body once.

void Clazz::Fun1()
{
    //Do stuff...
}
Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)

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. 
Run Code Online (Sandbox Code Playgroud)

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. 
Run Code Online (Sandbox Code Playgroud)