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 と呼ばれない関数
インクルードの使用方法についてさまざまな意見を読んだことがありますが、全体として、インクルードを防ぐためにコードを整理する適切な方法を理解するのは初心者のように感じます。
- 私は非常に混乱していますか?
- 実装ファイルでもヘッダー ガードを使用する必要がありますか?
- 前方宣言を使用する必要がありますか? もしそうなら、どのように?
- ヘッダーに基本クラスのインクルードのみが含まれているのに、実装にサブクラスのインクルードを含めたいと思うのはおかしいですか?
真剣にどんな指導も大歓迎です!