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

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