c++ でコンパイルエラーを修正したい。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
suntana
記事: 1
登録日時: 3年前

c++ でコンパイルエラーを修正したい。

#1

投稿記事 by suntana » 3年前

初めまして。先程ユーザー登録を済ませて初ログイン, 新規投稿させてもらっておりますサンタナです。よろしくお願いします。m(_"_)m

unix上での、gccコンパイルのc言語と、g++コンパイルのc++で、c++習得を目指しています。
c言語は習得済みで、c++は「独習c++」など一般書籍レベルなら理解しています。
c++でのデザインパターンを習得しようと思い、書籍「独習c++デザインパターン」を読んで、
本文のサンプルコードを手入力し、動作確認を通じて、
c++でのデザインパターンを習得しようとしています。
残念ながら、書籍「独習c++デザインパターン」には、
サンプルプログラムのCDや、ダウンロードデータがなく、
例題の全ソースコードが添付されておりません。
本文掲載の一部のソースコードを頼りに、手入力しています。
下記ソースコードをg++でコンパイルしましたが、コンパイルエラーが表示されて困っています。
いろいろ調べましたが、どのように修正すれば良いのか分からず、
本掲示板にご質問させていただきました。よろしくお願いします。

------------------------------------------------------------------------------------------------------
[1] 質問文
 [1.1] 自分が今行いたい事は何か
下記コードのコンパイルエラーを修正し、コンパイルが通って実行ファイル(a.out)が生成されたことを確認したい。

 [1.2] どのように取り組んだか(プログラムコードがある場合記載)
下記プログラムコードの通り手入力し、理解した内容のコメントを挿入しました。

 [1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
[suntana@localhost test]$ g++ test.cpp
00.cpp: 静的メンバ関数 ‘static DataObject* DataObject::create()’ 内:
00.cpp:23:24: エラー: invalid use of incomplete type ‘class FileObject’
return new FileObject;
^
00.cpp:15:7: エラー: forward declaration of ‘class FileObject’
class FileObject;
^
[suntana@localhost 01.factoryMethod]$

 [1.4] 今何がわからないのか、知りたいのか
下記コードのコンパイルエラーの修正方法が知りたいです。
書きコードはファイトりメソッドの実装方法を理解するための、
前段階のコードで、今回の本質問では、ファイトりメソッドの
本来の実装はこうだよ?という解答は求めておりません。
下記コードさえ実行できれよいと考えております。
なので、コメント以外、下記コードは書籍そのままで、
できるだけそのままの形で動かしたいと思っています。

[2] 環境  
 [2.1] OS : Linux(centos7)
 [2.2] コンパイラ名 : g++



// --------------------------------------------------------------------------

コード:

// ファクトりメソッド
    // 具象クラス名を明示せずにオブジェクトを生成したい。
    // これにより、クラスの切り替えが容易になる。
    // FileObject(開発環境) → DataBaseObject(本番環境)

// -------------------------------------
#include <iostream>
#include <map>
using namespace std;

class FileObject;  // この一行(前方参照)だけは、多数のコンパイルエラーを取る為に、私が追記した。

class DataObject
{
    public:
        static DataObject *create()
        {
            // 具象クラス名はここ1カ所だけ出現する。
            return new FileObject;
        }

        virtual string getName(int id) = 0;
};

class FileObject : public DataObject
{
    public:
        FileObject()
        {
            // ファイルからデータを読み、m_Dataに格納する。
        }

        string getName(int id)
        {
            // 引数で指定された製品idに対する製品名をm_Dataから検索して返す。
        }

    private:
        map<int, string> m_Data;
};

int main(void)
{
    DataObject *pDataObject = DataObject::create(); // こちらには具象クラス名は登場しない(させたくない)。
    string strName = pDataObject->getName(1);
}

以上 //

kansuke3
記事: 1
登録日時: 3年前

Re: c++ でコンパイルエラーを修正したい。

#2

投稿記事 by kansuke3 » 3年前

コード:

#include<string>
を入れ忘れています。
間違いだったらすみません。

Bull
記事: 149
登録日時: 9年前

Re: c++ でコンパイルエラーを修正したい。

#3

投稿記事 by Bull » 3年前

一通り C++ を学習されたのでしたら、何故エラーになっているのは分かっているものと思います。
とりあえずエラーをなくすのであれば、次のようにすればいいかと思います。
//@@@ とコメントを付けているところが変更している箇所です。

コード:

#include <iostream>
#include <map>
#include <string>
using namespace std;

class FileObject;  // この一行(前方参照)だけは、多数のコンパイルエラーを取る為に、私が追記した。

class DataObject
{
public:
	static DataObject *create();		//@@@ ここでは宣言だけ
	// {
	// 	// 具象クラス名はここ1カ所だけ出現する。
	// 	return new FileObject;
	// }

	virtual string getName(int id) = 0;
};

class FileObject : public DataObject
{
public:
	FileObject()
	{
		// ファイルからデータを読み、m_Dataに格納する。
	}

	string getName(int id)
	{
		// 引数で指定された製品idに対する製品名をm_Dataから検索して返す。
		return "";
	}

private:
	map<int, string> m_Data;
};

DataObject *DataObject::create()					//@@@ ここで関数を定義する
{
	return new FileObject;
}

int main(void)
{
	DataObject *pDataObject = DataObject::create(); // こちらには具象クラス名は登場しない(させたくない)。
	string strName = pDataObject->getName(1);
}
FileObject 型は DataObject 型を定義する前に宣言されているので、そのポインタを返すことは可能です。
ただし、DataObject の内部で new すること (インスタンス化) はできないので、FileObject 型を定義した後に、関数そのものを移動すれば、コンパイルできるようになります。

当方の環境
Windows 10
g++ (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
では、エラーもなくコンパイル、実行ができています。

アバター
あたっしゅ
記事: 664
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: c++ でコンパイルエラーを修正したい。

#4

投稿記事 by あたっしゅ » 3年前

コード:

// ファクトりメソッド
// 具象クラス名を明示せずにオブジェクトを生成したい。
// これにより、クラスの切り替えが容易になる。
// FileObject(開発環境) → DataBaseObject(本番環境)
// -------------------------------------
#include <iostream>
#include <map>
using namespace std;

//class FileObject;  // この一行(前方参照)だけは、多数のコンパイルエラーを取る為に、私が追記した。

class DataObject
{
    public:
        static DataObject *create();

        virtual string getName(int id) = 0;
};

class FileObject : public DataObject
{
    public:
        FileObject()
        {
            // ファイルからデータを読み、m_Dataに格納する。
        }

        string getName(int id)
        {
            // 引数で指定された製品idに対する製品名をm_Dataから検索して返す。
        }

    private:
        map<int, string> m_Data;
};
//
//
//
DataObject* DataObject::create()
        {
            // 具象クラス名はここ1カ所だけ出現する。
            return new FileObject;
        }
//
//
//
int main(void)
{
    DataObject *pDataObject = DataObject::create(); // こちらには具象クラス名は登場しない(させたくない)。
    string strName = pDataObject->getName(1);
}


// end.
あ、ほとんど同じレスがついてるね。でも、一応、up しておきます。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

サンタナ

Re: 修正してコンパイルが通りました!

#5

投稿記事 by サンタナ » 3年前

kansuke3 さん
Bull さん
あたっしゅ さん

サンタナです。ご回答ありがとうございました。
修正してコンパイルが通りました!
エラー原因の見当は付いていましたが、
コンストラクタの宣言の位置を具象クラスの定義の後に
することに気づかず、前方宣言での対応しか
思いつかなかった点に限界があったと思います。
<string> の取り込みもうっかり忘れており、
ただ取り込まなくてもコンパイルは通っていて、
コンパイル環境は、centos7 g++ ですが、
理由は調べていません。

大変助かりました!(感謝
書籍の通読理解がここでストップしていたので、
先に進められそうです。

返信

“C言語何でも質問掲示板” へ戻る