0

C++ で発生しているこの問題について質問があります。私はC++と学習が初めてです。私はオブジェクト指向プログラミングの経験があるので、正しい方法を探してこの問題を解決し、なぜそのようにする必要があるのか​​ を考えています。

クラス

各クラスをインターフェイス ヘッダー ファイルと実装 cpp ファイルに分けました。

最初のクラス「Alpha」は私の基本クラスです。

// a.h
#pragma once

class Alpha
{
public:
    virtual void myFunction();
};

アルファ版の実装:

// a.cpp
#include <iostream>
#include "a.h"

void Alpha::myFunction()
{
    std::cout << "Class Alpha myFunction" << std::endl;
}

次に、サブクラス「ベータ」があります。

// b.h
#pragma once
#include "a.h"
#include "a.cpp"

class Beta : public Alpha
{
public:
    virtual void myFunction();
};

ベータ版の実装:

// b.cpp
#include <iostream>
#include "b.h"

void Beta::myFunction()
{
    std::cout << "Class Beta myFunction" << std::endl;
}

次に、「ガンマ」と呼ばれるマネージャー クラスのようなものを作成します。

// g.h
#pragma once
#include <vector>
#include "a.h"
#include "a.cpp"

class Gamma
{
public:
    void run();
    std::vector<std::shared_ptr<Alpha>> alphaCollection;
};

ガンマの実装:

// g.cpp
#include "g.h"
#include "b.h"
#include "b.cpp"

void Gamma::run()
{
    Beta localBeta;

    alphaCollection.push_back(std::make_shared<Beta>(localBeta));

    // example usage
    alphaCollection.at(0)->myFunction();
}

それから最後に私のメイン:

#include "g.h";
#include "g.cpp";

int main()
{
    Gamma objectG;
    objectG.run();
}

なぜ私はこれをしているのですか

これらすべての目的は、さまざまな数の基本クラス オブジェクトの要素を挿入できる基本クラス Alpha のベクトルがマネージャーに必要であることです。

派生クラスの例として Beta を使用しましたが、実際の実装では、Charlie、Delta などの派生クラスがさらに多くなります。

目標は、Manager クラスの Gamma がベクター要素を Alpha オブジェクトとして操作できるようになり、各サブクラスが独自の動作を実行できるようになることです。

問題

上記の例をコンパイルできません。これは、Gamma の実装ファイルに「gh」と「bh」が含まれており、それぞれに「ah」と「a.cpp」が含まれているため、ヘッダー ガードがないため「a.cpp」が二重に含まれているためです。

  • エラー C2084: 関数 'void Alpha::myFunction(void)' には既に本体 a.cpp があります
  • エラー C2264: 'Alpha::myFunction': 関数の定義または宣言にエラーがあります。g.cpp と呼ばれない関数

インクルードの使用方法についてさまざまな意見を読んだことがありますが、全体として、インクルードを防ぐためにコードを整理する適切な方法を理解するのは初心者のように感じます。

  1. 私は非常に混乱していますか?
  2. 実装ファイルでもヘッダー ガードを使用する必要がありますか?
  3. 前方宣言を使用する必要がありますか? もしそうなら、どのように?
  4. ヘッダーに基本クラスのインクルードのみが含まれているのに、実装にサブクラスのインクルードを含めたいと思うのはおかしいですか?

真剣にどんな指導も大歓迎です!

4

3 に答える 3

0

.cpp ファイルではなく、ヘッダー ファイルのみを含める必要があります。

.cpp ファイルでヘッダー ガードを使用したくない場合。

ここでは事前宣言は必要ありません (ただし、代わりに使用できます)。

あなたの実装には「サブクラスのインクルード」は含まれていません。インターフェースを定義するヘッダーファイルが含まれています。あなたの ah のインクルードは gh で正しいです

于 2013-05-22T01:36:50.867 に答える