2012-03-06 97 views
90

我很困惑如何将简单类的实现和声明代码分离为新的头文件和cpp文件。例如,我将如何区分以下类的代码?将类代码分离为头文件和cpp文件

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y) 
    { 
    gx = x; 
    gy = y; 
    } 

    int getSum() 
    { 
    return gx + gy; 
    } 
}; 
+6

只是一对夫妇的意见:构造应该总是使用初始化列表,而不是设置的身体中的成员。对于一个很好的和简单的解释,请参见:http://www.codeguru.com/forum/showthread.php?t = 464084至少在大多数地方,惯例是将公共领域置于顶端。它不会影响任何内容,但是由于公共字段是您班级的文档,因此将它放在顶部是很有意义的。 – martiert 2012-03-06 08:14:55

+1

@martiert如果用户根据此建议移动了它们,但顶部的'public:'成员可能会影响_lot_,但却订购了成员之间的依赖关系,但尚未意识到成员是按其声明的顺序初始化的; - ) – 2016-04-16 15:00:37

+1

@underscore_d这是真的。但是,再次,我们都将警告编译为错误和我们可以想到的所有警告,对吗?这至少会告诉你,你搞砸了,但是,是的,人们使用的方式来警告,只是忽略它们:( – martiert 2016-04-19 07:58:57

回答

138

类声明进入头文件。添加#ifndef包括警卫很重要,或者如果您在MS平台上,也可以使用#pragma once。另外我省略了私有,默认情况下C++类成员是私有的。

// A2DD.h 
#ifndef A2DD_H 
#define A2DD_H 

class A2DD 
{ 
    int gx; 
    int gy; 

public: 
    A2DD(int x,int y); 
    int getSum(); 

}; 

#endif 

和实现云在CPP文件:

// A2DD.cpp 
#include "A2DD.h" 

A2DD::A2DD(int x,int y) 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
} 
+27

请记住,如果您正在进行模板编程,则必须将所有内容保存在.h文件中,以便编译器在编译时将实例化正确的代码。 – linello 2012-03-06 08:14:01

+0

即时消息得到一个错误的重复符号im不知道如何解决它.ld:重复符号A2DD :: A2DD(int,int)在./src/rstring.o和./src/A2DD.o体系结构x86_64 – drdrdr 2012-03-06 08:21:56

+1

你在头文件中有'#ifndef'的东西吗? – fritzone 2012-03-06 08:24:55

5

基本的函数声明/定义修改语法:

a2dd.h

class A2DD 
{ 
private: 
    int gx; 
    int gy; 

public: 
    A2DD(int x,int y); 

    int getSum(); 
}; 

a2dd.cpp

A2DD::A2DD(int x,int y) 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
} 
2

你留在头文件中的声明:

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y); // leave the declarations here 
    int getSum(); 
}; 

然后将这些定义放在执行文件中。

A2DD::A2DD(int x,int y) // prefix the definitions with the class name 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
} 

你可以混合使用这两种(离开例如头getSum()定义)。这很有用,因为它给编译器提供了更好的内联机会。但是这也意味着更改实现(如果保留在标题中)可能会触发重新生成包含标题的所有其他文件。

请注意,对于模板,您需要将其全部保留在标题中。

+1

将私有成员和函数放在头文件中不被视为泄漏实现细节? – Jason 2016-09-15 22:46:39

+0

@Jason,有点。这些是必要的*实施细节。例如,我必须知道一个类将在堆栈上消耗多少空间。其他编译单元不需要函数实现。 – 2016-09-17 22:53:16

3

A2DD.h

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y); 

    int getSum(); 
}; 

A2DD.cpp

A2DD::A2DD(int x,int y) 
    { 
    gx = x; 
    gy = y; 
    } 

    int A2DD::getSum() 
    { 
    return gx + gy; 
    } 

的想法是让所有的函数签名和成员在头文件。
这将允许其他项目文件在不需要知道实现的情况下查看该类的外观。

除此之外,你可以在实现中包含其他头文件而不是头文件。这很重要,因为头文件中包含的任何头文件将包含(继承)在包含头文件的任何其他文件中。

1

通常你只放声明和头文件非常短的内联函数:

例如:

class A { 
public: 
    A(); // only declaration in the .h unless only a short initialization list is used. 

    inline int GetA() const { 
    return a_; 
    } 

    void DoSomethingCoplex(); // only declaration 
    private: 
    int a_; 
}; 
9

一般而言,您的.h包含班级defing,这是您的所有数据和所有你的方法声明。像这样在你的情况:

A2DD.h: 

class A2DD 
{ 
    private: 
    int gx; 
    int gy; 

    public: 
    A2DD(int x,int y);  
    int getSum(); 
}; 

然后你的.cpp包含这样的方法实现:

A2DD.cpp: 

A2DD::A2DD(int x,int y) 
{ 
    gx = x; 
    gy = y; 
} 

int A2DD::getSum() 
{ 
    return gx + gy; 
}