2015-01-04 172 views
4

我一直使用cout打印語句,但現在我想通過學習passing the stream印刷,像void print(std::ostream&) const;我目前的打印功能看起來像使用std :: ostream的作爲參數傳遞給打印功能

template <class T> 

void Mystack<T>::print() 
{ 
    for (int i = 0; i <= top; i++) 
    { 
     std::cout << input[i] << " "; 
    } 
} 

我有2個問題:

  1. 從上面實現的正常打印功能切換到使用ostream的打印功能有什麼好處。
  2. 如何在我的函數中實現ostream。我試圖從互聯網來源瞭解ostream,但無法理解。請幫忙。

下面是完整的運行代碼:

//*************STACK CODE***************// 

//VERY GOOD EXAMPLE TO UNDERSTAND RULE OF THREE FOR BEGINEERS http://www.drdobbs.com/c-made-easier-the-rule-of-three/184401400 
//RULE OF THREE : Video : https://www.youtube.com/watch?v=F-7Rpt2D-zo 
//Thumb Rule : Whenever we have class which has members pointing to heap space we should implement Rule of three. 
//Concepts : Shallow Copy and Deep Copy 

#include <iostream> 
template <class T> 
class Mystack 
{ 
private: 
    T *input; 
    int top; 
    int capacity; 
public: 
    Mystack(); 
    ~Mystack(); 
    void push(T const& x); 
    void pop(); 
    T& topElement() const; 
    bool isEmpty() const; 
    void print(); 
}; 
template <class T> 
Mystack<T>::Mystack() 
{ 
    top = -1; 
    capacity = 5; 
    input = new T[capacity]; 
} 
template <class T> 
Mystack<T>::~Mystack() //Since we are using destructor explictly we need to apply Rule of 3 
{ 
    delete [] input; 
} 
template <class T> 
void Mystack<T>::push(T const& x) //Passing x by Const Reference // Valus of x cannot be changed now in the function! 
{ 
    if (top + 1 == capacity) 
    { 
     T *vec = new T[capacity * 2]; 
     for (int i = 0; i <= top; i++) 
     { 
      vec[i] = input[i]; 
     } 
     delete []input; // Avoiding Memory Leak. 
     input = vec; 
     capacity *= capacity; 
    } 
    top++; 
    std::cout << x; 
    std::cout << &x; 
    input[top] = x; 
} 
template <class T> 
void Mystack<T>::pop() 
{ 
    if (isEmpty()) 
    { 
     throw std::out_of_range("Stack Underflow"); 
    } 
    else 
    { 
     std::cout << "The popped element is" << input[top--]; 

    } 
} 
template <class T> 
bool Mystack<T>::isEmpty() const 
{ 
    if (top == -1) 
    { 
     std::cout << "Is Empty" << std::endl; 
     return true; 
    } 
    else 
    { 
     std::cout << "Not Empty" << std::endl; 
     return false; 
    } 
} 
template <class T> 
T& Mystack<T>::topElement() const 
{ 
    if (top == -1) 
    { 
     throw std::out_of_range("No Element to Display"); 
    } 
    else 
    { 
     std::cout << "The top element is : " << input[top]; 
     return input[top]; 
    } 
} 
template <class T> 
void Mystack<T>::print() 
{ 
    for (int i = 0; i <= top; i++) 
    { 
     std::cout << input[i] << " "; 
    } 
} 
int main() 
{ 
    Mystack<int> s1; 
    Mystack<float> s2; 
    Mystack<char> s3; 
    int choice; 
    int int_elem; 
    float float_elem; 
    char char_elem; 
    std::cout << "Enter the type of stack" << std::endl; 
    std::cout << "1. int "; 
    std::cout << "2. float "; 
    std::cout << "3. Char"<< std::endl; 
    std::cin >> choice; 
    if (choice == 1) 
    { 
     int ch = 1; 
     while (ch > 0) 
     { 
      std::cout << "\n1. Push "; 
      std::cout << "2. Top "; 
      std::cout << "3. IsEmpty "; 
      std::cout << "4. Pop "; 
      std::cout << "5. Exit "; 
      std::cout << "6. Print"<<std::endl; 
      std::cout << "Enter the choice" << std::endl; 
      std::cin >> ch; 
      switch (ch) 
      { 
      case 1: 
       std::cout << "Enter the number to be pushed" << std::endl; 
       std::cin >> int_elem; 
       s1.push(int_elem); 
       break; 
      case 2: 
       std::cout << "Get the TOP Element" << std::endl; 
       try 
       { 
        s1.topElement(); 
       } 
       catch (std::out_of_range &oor) 
       { 
        std::cerr << "Out of Range error:" << oor.what() << std::endl; 
       } 
       break; 
      case 3: 
       std::cout << "Check Empty" << std::endl; 
       s1.isEmpty(); 
       break; 
      case 4: 
       std::cout << "POP the element" << std::endl; 
       try 
       { 
        s1.pop(); 
       } 
       catch (const std::out_of_range &oor) 
       { 
        std::cerr << "Out of Range error: " << oor.what() << '\n'; 
       } 
       break; 
      case 5: 
       exit(0); 
      case 6: 
       s1.print(); 
       break; 
      default: 
       std::cout << "Enter a valid input"; 
       break; 
      } 
     } 
    } 
    else if (choice == 2) 
    { 
     int ch = 1; 
     while (ch > 0) 
     { 
      std::cout << "\n1. PUSH" << std::endl; 
      std::cout << "2. TOP" << std::endl; 
      std::cout << "3. IsEmpty" << std::endl; 
      std::cout << "4. POP" << std::endl; 
      std::cout << "5. EXIT" << std::endl; 
      std::cout << "6. Print" << std::endl; 
      std::cout << "Enter the choice" << std::endl; 
      std::cin >> ch; 
      switch (ch) 
      { 
      case 1: 
       std::cout << "Enter the number to be pushed" << std::endl; 
       std::cin >> float_elem; 
       s2.push(float_elem); 
       break; 
      case 2: 
       std::cout << "Get the TOP Element" << std::endl; 
       try 
       { 
        s2.topElement(); 
       } 
       catch (std::out_of_range &oor) 
       { 
        std::cerr << "Out of Range error:" << oor.what() << std::endl; 
       } 
       break; 
      case 3: 
       std::cout << "Check Empty" << std::endl; 
       s2.isEmpty(); 
       break; 
      case 4: 
       std::cout << "POP the element" << std::endl; 
       try 
       { 
        s2.pop(); 
       } 
       catch (const std::out_of_range &oor) 
       { 
        std::cerr << "Out of Range error: " << oor.what() << '\n'; 
       } 
       break; 
      case 5: 
       exit(0); 
      case 6: 
       s2.print(); 
       break; 
      default: 
       std::cout << "Enter a valid input"; 
       break; 
      } 
     } 
    } 
    else if (choice == 3) 
    { 
     int ch = 1; 
     while (ch > 0) 
     { 
      std::cout << "\n1. PUSH" << std::endl; 
      std::cout << "2. TOP" << std::endl; 
      std::cout << "3. IsEmpty" << std::endl; 
      std::cout << "4. POP" << std::endl; 
      std::cout << "5. EXIT" << std::endl; 
      std::cout << "6. Print" << std::endl; 
      std::cout << "Enter the choice" << std::endl; 
      std::cin >> ch; 
      switch (ch) 
      { 
      case 1: 
       std::cout << "Enter the number to be pushed" << std::endl; 
       std::cin >> char_elem; 
       s3.push(char_elem); 
       break; 
      case 2: 
       std::cout << "Get the TOP Element" << std::endl; 
       try 
       { 
        s3.topElement(); 
       } 
       catch (std::out_of_range &oor) 
       { 
        std::cerr << "Out of Range error:" << oor.what() << std::endl; 
       } 
       break; 
      case 3: 
       std::cout << "Check Empty" << std::endl; 
       s3.isEmpty(); 
       break; 
      case 4: 
       std::cout << "POP the element" << std::endl; 
       try 
       { 
        s3.pop(); 
       } 
       catch (const std::out_of_range &oor) 
       { 
        std::cerr << "Out of Range error: " << oor.what() << '\n'; 
       } 
       break; 
      case 5: 
       exit(0); 
      case 6: 
       s3.print(); 
       break; 
      default: 
       std::cout << "Enter a valid input"; 
       break; 
      } 
     } 
    } 
    else 
     std::cout << "Invalid Choice"; 
    std::cin.get(); 
} 
+3

'std :: cout'是一個特定的'std :: ostream'。還有其他的,如輸出文件流。也就是說,使用'std :: ostream'引用參數可以讓你打印文件和其他東西。但是,「打印」功能通常不是實現此目的的最佳方式。相反,您應該爲'std :: ostream'重載'operator <<',以便您可以只執行'cout << my_stack;',例如。 –

+1

'std :: cout' *是一個'std :: ostream'的實例,所以如果你的函數接受了這個類型的參數,你可以傳遞'std :: cout'包括其他'std :: ostream像文件,字符串流等。 – 0x499602D2

+0

不相關,你可能希望使你的棧[規則三](http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)遙遠的未來。您目前缺少幾件。 – WhozCraig

回答

5

切換到ostream版本的好處是,在情況下,你以後需要打印到其他地方,除了std::cout那麼你可以用做相同的功能實現,而在這一刻,如果你想打印到一個文件,你需要使用不同的功能。

如何實現它的一個例子是不是這樣做:

void print() 
{ 
    std::cout << "Print something always to cout" << std::endl; 
} 

你這樣做(注意我們傳遞的引用):

void print(std::ostream& os) 
{ 
    os << "Print something to wherever the caller wants to" << std::endl; 
} 

現在,而不是調用的功能等:

print(); 

你會打電話給這樣的功能打印到cout

print(std::cout); 

或類似這樣的打印到文件:

std::ofstream some_file("test.txt"); 
a.print(some_file); 

見,具有相同的功能,你可以決定你想要的打印去。

1

將流作爲參數傳遞給打印功能允許您使用具有不同流的相同打印功能,例如,您可以使用std::stringstream並將「輸出」作爲字符串的內容而不是輸出到控制檯或文件。我建議你爲「< <」操作符創建一個過載,這樣你的代碼在C++中看起來會更自然/習慣。我通常通過在我的班級中定義「操作員< <」的「朋友」超載來完成此操作。

下面是一個運算符示例< <重載,請注意,因爲它不是成員函數,所以您還需要將它傳遞給要輸出的對象的實例,我將其作爲對象的常量引用傳遞給它,

friend std::ostream & operator<<(std::ostream & o, const Mystack & stack) { 
     for (int i = 0; i <= stack.top; i++) 
     { 
      o << stack.input[i] << " "; 
     } 
     return o; 
    } 

這是你的類將會是什麼樣定義

template <class T> 
class Mystack 
{ 
private: 
    T *input; 
    int top; 
    int capacity; 
public: 
    Mystack(); 
    ~Mystack(); 
    void push(T const& x); 
    void pop(); 
    T& topElement() const; 
    bool isEmpty() const; 
    void print(); 
    friend std::ostream & operator<<(std::ostream & o, const Mystack & stack) { 
     for (int i = 0; i <= stack.top; i++) 
     { 
      o << stack.input[i] << " "; 
     } 
     return o; 
    } 
}; 

該功能,那麼你可能會使用這樣的

:您還可以通過值傳遞210
case 6: 
     std::cout << "The stack contents: " << s2 << std::endl; 
     break; 
相關問題