2

I have for homework to write my own abstract class Vector. I make some of the code, but when I try to compile it I have error. This is the code:

vector.hh:

#ifndef VECTOR__HH__
#define VECTOR__HH_

template<class T> class Vector {
    int capacity_;
    int size_;
    T* buffer_;

    void ensure_capacity(unsigned size);

public:
    Vector(int capacity=10) 
      : capacity_(capacity), size_(0), buffer_(new T[capacity])
    { }

    ~Vector() {
        delete []buffer_;
    }

    int size() const {
        return size_;
    }

    bool empty() const {
        return size_ == 0;
    }

    T& operator[](int n) {
        return buffer_[n];
    }

    const T& operator[](int n) const {
        return buffer_[n];
    }

    void clear() {
        // TODO
    }

    int capacity() const {
        return capacity_;
    }

    T& front() {
        return buffer_[0];
    }

    const T& front() const {
        return buffer_[0];
    }

    T& back() {
        return buffer_[size_-1];
    }

    const T& back() const {
        return buffer_[size_-1];
    }

    void push_back(const T& value);
};
#endif

vector.cc:

#include "vector.hh"

template<class T> 
void Vector<T>::ensure_capacity(unsigned size) {
    if(capacity_>size+1) {
        return;
    } 

    capacity_ = capacity_ ==0?1:capacity_;

    while(capacity_<size+1) {
        capacity_*=2;
    }

    T* old_buffer = buffer_;
    buffer_ = new T[capacity_];
    memcpy(buffer_, old_buffer, sizeof(T)*size_);

    delete [] old_buffer;
}

template<class T>
void Vector<T>::push_back(const T& value) {
    ensure_capacity(size()+1);

    buffer_[size_] = value;
    size_++;
    buffer_[size_] = '/0';
}

main.cc:

#include "vector.hh"
#include <iostream>
using namespace std;

int main(int argc, char* argv[]) {
    Vector<int> v(2);
    v.push_back(10);

    cout << v[0];

    return 0;
}

And error is:

g++ -c -o main.o main.cc
g++ -Wall -g vector.o main.o -o hw02vector
main.o: In function 'main':
main.cc:(.text+0x37): undefined reference to 'Vector<int>::push_back(int const&)'
collect2: ld returned 1 exit status
make: * [hw02vector] Error 1

iammilind
  • 68,093
  • 33
  • 169
  • 336
nyanev
  • 11,299
  • 6
  • 47
  • 76

2 Answers2

7

The linker error is coming because, for template classes the definition should always be visible. Either you can move all the content of vector.cc into vector.h. Or you can simply include vector.cc wherever you include vector.h.

side note:

Following lines in your .h file doesn't help:

#ifndef VECTOR__HH__
#define VECTOR__HH_

make both the macros similar such as, VECTOR__HH. This macros are used to avoid multiple inclusion of files.

iammilind
  • 68,093
  • 33
  • 169
  • 336
5

In template programmming, the definition of the functions should be visible where the class template is defined. That is usually done by defining the functions inside the class itself.

So there are two ways you can solve your problem:

  • Move all the definitions from vector.cpp to vector.hh (which is in fact the usual solution). And delete Vector.cpp as its not needed.
  • Or, include the vector.cpp file at the end of vector.hh file, after the definition of Vector class template, like this:

    #ifndef VECTOR__HH__
    #define VECTOR__HH__  //<--- corrected this also!
    
    template<class T> 
    class Vector {
       //...
    };
    
    //...
    
    #include "vector.cpp"
    
    #endif VECTOR__HH__
    
Nawaz
  • 353,942
  • 115
  • 666
  • 851