簡體   English   中英

將 class 代碼分離為 header 和 cpp 文件

[英]Separating class code into a header and cpp file

我對如何將簡單 class 的實現和聲明代碼分離到新的 header 和 cpp 文件中感到困惑。 例如,我將如何分隔以下 class 的代碼?

class A2DD
{
  private:
  int gx;
  int gy;

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

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

類聲明進入頭文件。 添加#ifndef包含防護很重要。 大多數編譯器現在也支持#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;
}

 

通常,您的 .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;
}

重要的是要向在更廣泛的方式研究該主題時遇到這個問題的讀者指出,如果您只想將項目拆分為文件,則不需要接受答案的過程。 僅當您需要單個類的多個實現時才需要它。 如果每個類的實現是一個,那么每個類只需要一個頭文件就足夠了。

因此,從接受的答案的例子中,只需要這部分:

#ifndef MYHEADER_H
#define MYHEADER_H

//Class goes here, full declaration AND implementation

#endif

#ifndef 等預處理器定義允許它被多次使用。

附注。 一旦您意識到 C/C++ 是“愚蠢的”並且#include 只是一種說“在此位置轉儲此文本”的方式,主題就會變得更加清晰。

基本上是函數聲明/定義的修改語法:

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

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

這個想法是在頭文件中保留所有函數簽名和成員。
這將允許其他項目文件查看類的外觀,而無需知道實現。

除此之外,您還可以在實現中包含其他頭文件而不是頭文件。 這很重要,因為頭文件中包含的任何頭文件都將包含(繼承)在包含頭文件的任何其他文件中。

您將聲明保留在頭文件中:

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()定義)。 這很有用,因為它為編譯器提供了更好的內聯機會。 但這也意味着更改實現(如果留在標題中)可能會觸發包含標題的所有其他文件的重建。

請注意,對於模板,您需要將其全部保留在標題中。

通常你只在頭文件中放置聲明和非常短的內聯函數:

例如:

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

我不會太引用你的例子,因為它對於一般答案來說非常簡單(例如它不包含模板化函數,這迫使你在標題上實現它們),我遵循的經驗法則是pimpl成語

它有很多好處,因為您可以獲得更快的編譯時間和語法糖:

class->member而不是class.member

唯一的缺點是您支付的額外指針。

這將是一個解決方案:

.hpp 文件:

class A2DD
{
  private:
  int gx;
  int gy;

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

.cpp 文件:

class A2DD
{
  private:
  int gx;
  int gy;

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM