2017-02-16 5 views
0

で宣言されていないあなたは重複としてこの質問をマークする前に、私はthisポストを見て、サイト上の他の類似のものを持っていたことを実感してください。私の問題は、可変スコープやプリプロセッサの仕組みを理解することではありません。私はそれらを持っている。C++変数のスコープ

私のコードでこの厄介な問題を理解することはできません。私はちょうどC + +を使用してスタックのデータ構造をモデル化しようとしています。コンパイラはsizecapacityがこのスコープ内で宣言されていないと不平を続けています(Stack.cpp)。 3つのファイルがあります。

  • Stack.h
  • Stack.cpp
  • MAIN.CPP

以下は、ヘッダーファイルのコードスニペットと.cppファイルです:

Stack.h

#ifndef STACK_H_ 
#define STACK_H_ 


#include <iostream> 
#include <string> 


using namespace std; 


template<typename T> 
class Stack 
{ 
    public: 
     Stack(); 
     void push(T item); 
     T pop(); 

    private: 
     int size; 
     const int capacity = 10; 
     T items[]; 
}; 


#endif 

Stack.cpp

#include "Stack.h" 

using namespace std; 

template<typename T> 
Stack::Stack() : items[capacity] 
{ 
    size = 0; 
} 


template<typename T> 
void Stack::push(T item) 
{ 
    if(size == capacity) 
    { 
     cout << "No more room left. Unable to add items."; 
    } 
    else 
    { 
     items[size-1] = item; 
     size++; 
    } 
} 


template<typename T> 
T Stack::pop() 
{ 
    if(size == 0) 
    { 
     cout << "Stack is empty. There is nothing to remove."; 
    } 
    else 
    { 
     size--; 
    } 
} 

コンパイラはまた、妙に「『テンプレートクラスのスタックは、』テンプレートパラメータのボイドスタックなしで使用::プッシュ(Tアイテム)」と文句を言いあまり意味がありません、見てメンバ関数の前にテンプレートヘッダをどのように使用したかのように。

誰かが間違ったことを明確にしてもらえますか?

+1

http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-fileがあなたをより良い方向に誘導します。また、テンプレート化されたtypenameはStack です。 –

答えて

0

コンパイラは、妙に私は、コンパイラがでていることを教えてくれしようとしていると思う「テンプレートパラメータのボイドスタックなしで使用 『テンプレートクラスのスタック』 ::プッシュ(Tアイテム)」

と文句を言い使用したcppファイルStackStack<T>を使用してください。たとえば、あなたのpush宣言はそう、私は、あなたの問題を経ていくつかの問題を修正し、(単に推奨)を最適化

template<typename T> 
void Stack<T>::push(T item) 
// ... etc ... 
1

...次のようになります。

  1. 最初の問題は、あなたということでしたクラス全体をテンプレート化して機能を分離するだけでなく、他の人が以前に答えました。したがって、コンストラクタを除く各関数でテンプレートリストを使用する必要があります。
  2. 第二の問題は、あなたが最初のものは、コンパイラは文句を言わないコードをコンパイル修正するときは、(あなたが行うことができないというテンプレートクラスを使用した - 少なくともないで、通常の方法Explanation)の定義と実装のために別々のファイルを使用しているため、発生します。それはこのように定義されているよう
  3. 第3の最後の問題は、(私の変更は単なる一時的な修正である)、それは何かを返す必要があり、体に何も返さないことを、ポップな機能で発生します。
  4. プッシュで固定サイズが変更されます。

の最適化:

  1. 名前空間stdを使用して削除しました。 Explanation
  2. (少なくともスタックのインスタンス化時には)ユーザーが設定できる変更された容量。
  3. 変更された項目array to std :: unique_ptr動的に作成された配列を指すスマートポインタ。
  4. コンストラクタにメンバ初期化子リストを追加しました。

コード(Stack.h):

#ifndef STACK_H_ 
#define STACK_H_ 

#include <iostream> 
#include <memory> // for unique_ptr 

//using namespace std; // it is better to not use using namespace, for avoiding of problems in the future 

template<typename T> 
class Stack { 
public: 
    Stack(const unsigned int& capacity = 10); // usually stacks are defined with user settable capacity 
    void push(T item); 
    T pop(); 
private: 
    unsigned int size; 
    unsigned int capacity; 
    std::unique_ptr<T[]> items; 
}; 

// such templated functions (below) cannot be implemented in other file 

template<typename T> 
Stack<T>::Stack(const unsigned int& capacity) : 
    capacity(capacity), 
    items(new T[capacity]), 
    size(0) {} 

template<typename T> 
void Stack<T>::push(T item) { 
    if (size == capacity) { 
     std::cout << "No more room left. Unable to add items." << std::endl; 
    } 
    else { 
     items[size++] = item; // you should put item at index size, after that increase it by one 
    } 
} 

template<typename T> 
T Stack<T>::pop() { 
    // for such defined function you need to return something of type T 
    if (size == 0) { 
     std::cout << "Stack is empty. There is nothing to remove." << std::endl; 
     return 0; // maybe return empty object? 
    } 
    else { 
     return items[--size]; // probably return removed object 
    } 
} 

#endif 

コード(main.cppに):

#include "Stack.h" 

int main() { 
    Stack<int> stack; 
    for (int e = 0; e < 11; e++) { 
     stack.push(e); 
    } 
    for (int i = 0; i < 11; i++) { 
     std::cout << stack.pop() << std::endl; 
    } 
    return 0; 
} 

は、この情報がお役に立てば幸いです。