47858


(参考書:明解c++中級編) コメントで書かれている1,2,3となっている文法の意味がわからないので質問しました。

  1. friendクラスと宣言されてる部分です、フレンドはそのクラスに属してるわけではなくクラスの非公開部にアクセスできるところまではわかるのですがこの文脈ではどんな意味なのでしょうか？
  2. `new Type(x)`のところでなぜ`new Type(x)`するのでしょうか？
  3. `*(top->data)`とありますがそれは`tom->data`の`data`がポインタのため [*data]data のポインタの中身を指定してるからでしょうか？

[code]

    ////////////////////////class_stackクラス/////////
    #pragma once
    // スタック 抽象クラステンプレート
    
    #ifndef ___Class_Stack
    #define ___Class_Stack
    
    //===== スタック 抽象クラステンプレート =====//
    template <class Type> class Stack {
    public:
        //class Overflow { };                // 満杯スタックへのプッシュに対する例外
        //class Empty { };                   // 空のスタックからのポップに対する例外
        virtual ~Stack() = 0;                // デストラクタ
        virtual void push(const Type&) = 0;  // プッシュ
        virtual Type pop() = 0;              // ポップ
    };
    
    //--- デストラクタ ---//
    template <class Type> Stack<Type>::~Stack() { }
    
    #endif
    
    ////////////////////////////class_ListStackクラス//////////////
    // スタック クラステンプレート（線形リストによる実現）
    
    #ifndef ___Class_ListStack
    #define ___Class_ListStack
    using namespace std;
    #include "Stack.h"
    
    //===== 線形リストによるスタック クラステンプレート =====//
    template <class Type> class ListStack : public Stack<Type> {
    
        //=== ノード ===//
        template <class Type> class Node {
            friend class ListStack<Type>;  // 1つ目の質問箇所
            Type* data;                    // データ
            Node* next;                    // 後続ポインタ（後続ノードへのポインタ）
        public:
            Node(Type* d, Node* n) : data(d), next(n) { }
        };
    
        Node<Type>* top;    // 先頭ノードへのポインタ
        Node<Type>* dummy;  // ダミーノードへのポインタ
    
    public:
    
        //----- 満杯スタックへのプッシュに対する例外 -----//
        class Overflow { };
    
        //----- 空のスタックからのポップに対する例外 -----//
        class Empty { };
    
        //--- コンストラクタ ---//
        ListStack() {
            top = dummy = new Node<Type>(NULL, NULL);
        }
    
        //--- デストラクタ ---//
        ~ListStack() {
            Node<Type>* ptr = top;
            while (ptr != dummy) {
                Node<Type>* next = ptr->next;
                delete ptr->data;
                delete ptr;
                ptr = next;
            }
            delete dummy;
        }
    
        //--- プッシュ ---//
        void push(const Type& x) {
            Node<Type>* ptr = top;
            try {
                top = new Node<Type>(new Type(x), ptr);  // 2つ目の質問箇所
            }
            catch (const bad_alloc&) {
                throw Overflow();
            }
        }
    
        //--- ポップ ---//
        Type pop() {
            if (top == dummy)  // スタックは空
                throw Empty();
            else {
                Node<Type>* ptr = top->next;
                Type temp = *(top->data);    // 3つ目の質問箇所
                delete top->data;
                delete top;
                top = ptr;
                return temp;
            }
        }
    };
    
    #endif
    
    //////////////int main()関数///////////////////////////////
    
    #include "conio.h"
    #include <iostream>
    #include "ListStack.h"
    using namespace std;
    
    int main()
    {
        Stack<int> *s = new ListStack<int>();
    
        int menu;
        int x;
    
        while (1) {
            cout << "(1)プッシュ (2)ポップ (0)終了：";
            cin >> menu;
            if (menu == 0) break;
    
            switch (menu) {
            //--- ブッシュ ---//
            case 1:
                cout << "データ：";
                cin >> x;
    
                try {
                    s->push(x);
                }
                catch (const ListStack<int>::Overflow&) {
                    cout << "\aオーバフローしました。\n";
                }
                break;
            //--- ポップ ---//
            case 2:
                try {
                    x = s->pop();
                    cout << "ポップしたデータは" << x << "です。\n";
                }
                catch (const ListStack<int>::Empty&) {
                    cout << "\aスタックは空です。\n";
                }
                break;
            default:
                cout << "1/2/0/のいずれかの数字を入力してください\n";
            }
        }
    
        delete s;
        _getch();
        return 0;
    }
    
[/code]


CC BY-SA 4.0
2018-08-25T08:10:47.583
47802
2018-08-27T13:33:42.180
2018-08-26T23:38:06.097
19110
question
c++
C++参考書で解説の無い部分のコードの意図が分からない


  1. コードに書いてあるとおりの意味です。`ListStack<Type>` が `Node<Type>` の非公開メンバ `data` と `next` にアクセスできます。それら以外のクラスが`data`と`next`を書き換えたりすると整合性が取れなくなるので、非公開としているのでしょう。  
(ただし、この場合`Node<Type>`自体が`ListStack<Type>`以外から見えないので、`data`と`next`は`public`にしてもさほど変わりません。)

  2. `push()`の引数になっている`x`は、いつデストラクトされるか`ListStack`クラスは知ることができません。ですので、`x`のアドレスを保持することはできず、自分で保持するためにはコピーする必要があります。`Node<Type>::data`がポインタなので`new`してますが、`Type`がコピー可能という前提であれば、`Node<Type>::data`をポインタではなく実体にして、ここでは`new Node<Type>(x, ptr)`としてコピーするのも手です。

  3. はい


CC BY-SA 4.0
2018-08-27T13:33:42.180
47858
2018-08-27T13:33:42.180
3475
47802
answer