将类代码分隔为标头和cpp文件

时间:2012-03-06 08:05:56

标签: c++ oop class

我对如何将一个简单类的实现和声明代码分成新的头文件和cpp文件感到困惑。例如,我如何分离下一个类的代码?

class A2DD
{
  private:
  int gx;
  int gy;

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

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

8 个答案:

答案 0 :(得分:197)

类声明进入头文件。添加#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;
}

答案 1 :(得分:15)

通常你的.h包含类定义,它是你的所有数据和所有方法声明。在你的情况下像这样:

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;
}

答案 2 :(得分: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;
}

答案 3 :(得分:4)

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;
  }

这个想法是将所有功能签名和成员保留在头文件中 这将允许其他项目文件在不必了解实现的情况下查看类的外观。

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

答案 4 :(得分:4)

重要的一点是要向读者指出,在以更广泛的方式研究该主题时,绊倒这个问题的情况是,在仅要将项目拆分为文件的情况下,不需要接受的答案即可。仅当您需要单个类的多个实现时才需要它。如果您每个类的实现是一个,那么每个类的一个头文件就足够了。

因此,从接受的答案的示例中,仅需要这一部分:

#ifndef MYHEADER_H
#define MYHEADER_H

//Class goes here, full declaration AND implementation

#endif

#ifndef等预处理器定义允许多次使用它。

PS。一旦您意识到C / C ++是“哑巴”,并且#include只是说“在此位置转储此文本”的一种方式,该主题将变得更加清晰。

答案 5 :(得分:3)

您将声明保留在头文件中:

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()定义)。这很有用,因为它为编译器提供了更好的内联机会。但这也意味着更改实现(如果留在标题中)可能会触发重建包含标题的所有其他文件。

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

答案 6 :(得分: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_;
 };

答案 7 :(得分:0)

我不会引用您的示例,因为对于一般性回答而言,它非常简单(例如,它不包含模板化函数,这些函数迫使您在标头上实现它们),根据我的经验法则是pimpl idiom

当您获得更快的编译时间和语法糖时,它具有很多好处:

class->member而不是class.member

唯一的缺点是您需要支付额外的指针。