質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • C++

    3590questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

c++ ファクトリでオブジェクトを作成後、そのオブジェクトをポインタで指すには

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,053

fgfnabwym

score 66

このプログラムは値を格納する際にキューかスタック化を選択することができます。
ファクトリを作ることは例を見てできたのですが、値の取り出し方が分かりません。

このプログラムをコンパイルすると次のようにエラーが出ます。値を取り出す際にその値のあるオブジェクトを指さなければいけません。その差し方が間違ってるのだと思いますが、直し方が分かりません。

ques12n3s.cpp: In function ‘int main()’:
ques12n3s.cpp:145: error: expected primary-expression before ‘;’ token
ques12n3s.cpp:147: error: expected primary-expression before ‘;’ token

どう直せばいいでしょうか。

#include <iostream>
#include <cstdlib>
#include <cctype>
#include <typeinfo>
using namespace std;

// 抽象クラス 少なくとも1個の純粋仮想関数を含んでいるクラス
class DataStruct {
public:
    DataStruct *head; // リスト先頭へのポインタ
    DataStruct *tail; // リスト末尾へのポインタ
    DataStruct *next; // 次項目へのポインタ
    int num;    // 格納される値
    DataStruct () { head = tail = next = NULL; }
    virtual void store(int i) = 0; // 純粋仮想関数 継承されて初めて存在できる
    virtual int retrieve() = 0;    // 純粋仮想関数
};

// キュー型リストの作成
class queue : public DataStruct {
public:
    void store(int i);
    int retrieve();
};

void queue::store(int i)
{
    DataStruct *item;
    item = new queue;

    if (!item) {
        cout << "メモリ割り当てエラー.\n";
        exit(1);
    }
    item->num = i;
cout << "キューに格納される値  " << i << '\n';

    // リスト末尾に置く
    if (tail) tail->next = item;
    tail = item;
    item->next = NULL;
    if (!head) head = tail;
}

int queue::retrieve()
{
    int i;
    DataStruct *p;

    if (!head) {
        cout << "リストは空です\n";
        return 0;
    }

    // リスト先頭から取り除く
    i = head->num;
    p = head;
    head = head->next;
    delete p;
cout << "キューから取り出される値  " << i << '\n';
    return i;
}

// スタック型リストの作成
class stack : public DataStruct {
public:
    void store(int i);
    int retrieve();
};
void stack::store(int i)
{
    DataStruct *item;
    item = new stack;

    if (!item) {
        cout << "メモリ割り当てエラー\n";
        exit(1);
    }
    item->num = i;
cout << "スタックに格納される値  " << i << '\n';

    // スタックのような操作になるよう、リスト最前部に置く
    if (head) item->next = head;
    head = item;
    if(!tail) tail = head;
}

int stack::retrieve()
{
    int i;
    DataStruct *p;

    if (!head) {
        cout << "リストは空です\n";
        return 0;
    }

    // リスト先頭から取り除く
    i = head->num;
    p = head;
    head = head->next;
 delete p;
cout << "スタックから取り出される値  " << i << '\n';
    return i;
}

// オブジェクトを作るファクトリ
DataStruct *DataStructFactory(char what)
{
    switch (what) {
        case 'q':
            return new queue;
        case 's':
            return new stack;
    }
}

int main()
{
    DataStruct *p;
    char ch;
    int i;

    // 値を格納
    for (i = 0;i < 10;i++) {
        cout << "キューかスタックを選択(q/s):";
        cin >> ch;
        ch = tolower(ch);
        p = DataStructFactory(ch);  // 次のオブジェクトを取得する

        cout << typeid(*p).name() << endl;

        // 値をキューまたはスタックに格納
        p->store(i);
    }

    // 値を取りだす
    cout << "Tを入力すると終了します\n";
    for (;;) {
        cout << "キューとスタックのどちらを取りだしますか(q/s):";
        cin >> ch;
        ch = tolower(ch);
        if(ch == 't') break;
        if(ch == 'q') {
            p =queue ;
        } else {
            p =stack ;
        }
        cout << p->retrieve() << '\n';
    }

    return 0;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

このコードだとどういうことがやりたいのかよく判りませんけど・・最初の for ループで queue や stack をループ毎に作成しているようなのですが、それであっていますか? これだと、要素数が1個の queue や stack が合計 10 個作成されるだけですけれども・・

それとも、このファクトリは静的な queue や stack のインスタンスを返すのが正しいのではありませんか?

例えば次のようにです。

DataStruct *DataStructFactory(char what)
{
    static queue q;
    static stack s;

    switch (what) {
        case 'q':
            return &q;
        case 's':
            return &s;
    }
}

もし、そうなのだとしたら、main 関数のコンパイルエラーになっている箇所は次のようになります。

    for (;;) {
        cout << "キューとスタックのどちらを取りだしますか(q/s):";
        cin >> ch;
        ch = tolower(ch);
        if(ch == 't') break;
        //if(ch == 'q') {
        //    p =queue ;
        //} else {
        //    p =stack ;
        //}
        p = DataStructFactory(ch);
        cout << p->retrieve() << '\n';
    }

ただ、これだと ファクトリ ではありませんけど・・・

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/21 01:03

    ngyukiさん、回答ありがとうございます。
    問題には動的に確保するとは書いてなかったのですが、自分で勝手に動的に確保していました。

    教えていただいたように一旦直してみます。

    キャンセル

  • 2015/07/21 01:13

    エラーが消えて動くようになりました。

    ngyukiさん、ありがとうございました。

    キャンセル

  • 2015/07/21 01:19 編集

    見た感じでは、ファクトリの実装方法とキュー・スタックの動作の違いが分かれば良いような気がしますが。

    そうだとすると、最初に1度キューかスタックの選択をさせ、あとは生成したインスタンスに対する値の詰め込みと取り出しをする処理を書くだけでいいと思いますよ。

    キューとスタックのクラスには、emptyを判定する関数があった方が良いとは思いますけど。

    キャンセル

  • 2015/07/21 01:31

    pikovoltさん、教えて下さりありがとうございます。
    参考書を見てもあまり理解できず、時間だけが過ぎてしまい。

    もう一度直してみます。

    キャンセル

関連した質問

同じタグがついた質問を見る

  • C++

    3590questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。