tags:

views:

641

answers:

1

Hi,

I am using C++ and I am trying to create a templated class (a Stack). I would like to define the copy constructor and the assignment operator.

There are defined in the header and then I implement them in the cpp file.

Here are the problems I get: - For the copy constructor: prototype for ‘Stack::Stack(const Stack&)’ does not match any in class ‘Stack’ - For the assignement operator: stack.cpp:28: error: no ‘Stack& Stack::operator=(const Stack&)’ member function declared in class ‘Stack’ - For the constructor: stack.cpp:4: error: candidate is: Stack::Stack()

Here is the header file:

// stack.hpp

#ifndef STACK_HPP
#define STACK_HPP


#include <stdio.h>
#include <assert.h>


template <class T> 
class Stack
{

public:
  Stack();
  ~Stack();

  Stack(const Stack&);
  Stack& operator=(const Stack&);


private:
  T* v_;
  size_t vsize_;
  size_t vused_;

};

Here is the cpp file:

// stack.cpp

#include "stack.hpp"

template <class T> 
Stack<T>::Stack() :
  v_(0), 
  vsize_(10), 
  vused_(0) 
{
  v_ = new T[vsize_];
}

template <class T> 
Stack<T>::~Stack()
{
  delete[] v_;
}


//  Stack(const Stack&);
template <class T> Stack<T>::Stack( const Stack<T>& other) :
  v_(NewCopy(other.v, other.vsize_, other.vsize_)),
  vsize_(other.vsize_),
  vuser_(other.vused)
{
}

//  Stack& operator=(const Stack&);
template<class T> Stack<T>& Stack<T>::operator=(const Stack<T>& other)
{
  if (this != &other)
  {
    T* v_new = NewCopy(other.v_, other.vsize_, other.vsize__;
    delvete v_;
    v_ = v_new
    vsize_ = other.vsize_;
    vused_ = other.vused_;
  }
  return *this

}

One last thing, here is the log from the compilation:

g++ -c stack.cpp -o stack.o 
stack.cpp:20: error: prototype for ‘Stack<T>::Stack(const Stack<T>&)’ does not match any in class ‘Stack<T>’
stack.cpp:4: error: candidate is: Stack<T>::Stack()
stack.cpp:28: error: no ‘Stack<T>& Stack<T>::operator=(const Stack<T>&)’ member function declared in class ‘Stack<T>’

I am sure this is only a small typo error but I cannot seem to find it. Thanks for your help

+4  A: 

You can't compile templates into separate compilation units. In short, all the template code has to all be in one header. This is likely whats causing your problem.

The reason is that templates don't define true classes. Templates specify how code can be generated. So when you make a

 Stack<int> myStack;

The compiler uses the template to generate a copy constructor:

 Stack<int>::Stack<int>( const Stack<int>& src);

This is a completely different type than a

 Stack<float>

which will define a completely independent copy constructor, and completely independent set of methods.

One option many use is to include the cpp in the header, in a reverse kind-of-way.

ie in Stack.hpp, at the bottom

#include "Stack.cpp"

but that kind of hides the fact that really its all just plopped into one header.

Doug T.
Thanks ! I did not know that. I changed it and after correcting a few errors it works.So if I understand well, there are no ways to separate headers and implementation of a templated class ?Maybe by using an interface ?
jules
Yeah you can use inheritance with your templates and force them all to inherit from a common base class (stack<int> and stack<float> both inherit from IStack). This can be rather useful.
Doug T.
separating works well, and the code as presented should have compiled i think (didn't spot any bug). If you know beforehand which types you will use to instantiate, you can explicitly instantiate within the .cpp file, and be fine with hiding the code. But normally, you will have the defintion of a template in the same file as the template declaration itself, including all its member functions.
Johannes Schaub - litb
Yes in fact this should have worked as listed as litb says. You definitely should have everything in just on header, but it looks like in your copy constructor the Stack you specified didn't have a template argument associated with it (should be Stack<T>) I'd say.
Doug T.
Anyway, delvete v_; --> delete[] v_; and add a semicolon at the end of operator= definition. You probably had the header file out of date or something so the class declaration didn't contain the op= or cctor decl yet. My silly guess :)
Johannes Schaub - litb