简体   繁体   中英

C++ template class reference pass by-reference

i was studying template classes andi have seen a tutorial code in a book. There is a class named Stack as the following:

// Stack class template.
#ifndef STACK_H
#define STACK_H

template< typename T >
class Stack 
{
public:
   Stack( int = 10 ); // default constructor (stack size 10)

   // destructor
   ~Stack() 
   { 
      delete [] stackPtr; // deallocate internal space for stack
   } // end ~Stack destructor

   bool push( const T& ); // push an element onto the stack
   bool pop( T& ); // pop an element off the stack

   // determine whether Stack is empty
   bool isEmpty() const 
   { 
      return top == -1; 
   } // end function isEmpty

   // determine whether Stack is full
   bool isFull() const 
   { 
      return top == size - 1; 
   } // end function isFull

private:
   int size; // # of elements in the stack
   int top; // location of the top element (-1 means empty)
   T *stackPtr; // pointer to internal representation of the stack
}; // end class template Stack

// constructor template
template< class T >
Stack< T >::Stack( int s )
   : size( s > 0 ? s : 10 ), // validate size
     top( -1 ), // Stack initially empty
     stackPtr( new T[ size ] ) // allocate memory for elements
{
   // empty body
} // end Stack constructor template

// push element onto stack;
// if successful, return true; otherwise, return false
template< class T >
bool Stack< T >::push( const T &pushValue )
{
   if ( !isFull() ) 
   {
      stackPtr[ ++top ] = pushValue; // place item on Stack
      return true; // push successful
   } // end if

   return false; // push unsuccessful
} // end function template push

// pop element off stack;
// if successful, return true; otherwise, return false
template< class T > 
bool Stack< T >::pop( T &popValue )
{
   if ( !isEmpty() ) 
   {
      popValue = stackPtr[ top-- ]; // remove item from Stack
      return true; // pop successful
   } // end if

   return false; // pop unsuccessful
} // end function template pop

#endif

Also there is a main tester function that uses a function template as following.

// Fig. 14.4: fig14_04.cpp
// Stack class template test program. Function main uses a 
// function template to manipulate objects of type Stack< T >.
#include <iostream>
#include <string>
#include "Stack.h" // Stack class template definition
using namespace std;

// function template to manipulate Stack< T >               
template< typename T >                                         
void testStack(                                             
   Stack< T > &theStack, // reference to Stack< T >         
   T value, // initial value to push                        
   T increment, // increment for subsequent values          
   const string stackName ) // name of the Stack< T > object
{                                                           
   cout << "\nPushing elements onto " << stackName << '\n'; 

   // push element onto Stack                               
   while ( theStack.push( value ) )                         
   {                                                        
      cout << value << ' ';                                 
      value += increment;                                   
   } // end while                                           

   cout << "\nStack is full. Cannot push " << value         
      << "\n\nPopping elements from " << stackName << '\n'; 

   // pop elements from Stack                               
   while ( theStack.pop( value ) )                          
      cout << value << ' ';                                 

   cout << "\nStack is empty. Cannot pop" << endl;                
} // end function template testStack                                 

int main()
{
   Stack< double > doubleStack( 5 ); // size 5  
   Stack< int > intStack; // default size 10

   testStack( doubleStack, 1.1, 1.1, "doubleStack" );
   testStack( intStack, 1, 1, "intStack" );
   system("pause");
} // end main

What could be reason usage of reference in testStack function? When i make change denition as

Stack< T > theStack,

i get an error message that says "debug assertion failed" after program ends.

There is no copy constructor in Stack, so when you replace

Stack<T>& 

to

Stack<T> 

the default ctor is used.

The second copy is destroying already cleaned pointer.

delete[] stackPtr; 

i think the best think is using reference when using a class's instance as a function parameter. But i just wanted to try copy constructor and added following code into Stack class and nothing changed. Error message appeared again with program end. What could be the correct copy constructor function?

// copy constructor template
template< typename T >
Stack< T >::Stack(const Stack &something)
{
    top = something.top;
    size = something.size;
    stackPtr = something.stackPtr;
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM