Зачем получать ошибку компоновщика с вектором? - PullRequest
2 голосов
/ 09 мая 2011

У меня есть домашнее задание, чтобы написать свой собственный абстрактный класс Vector. Я делаю часть кода, но когда я пытаюсь его скомпилировать, у меня возникает ошибка. Это код:

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;
}

И ошибка:

g ++ -c -o main.o main.cc
g ++ -Wall -g vector.o main.o -o hw02vector
main.o: в функции 'main':
main.cc:(.text+0x37): неопределенная ссылка на 'Vector<int>::push_back(int const&)'
collect2: ld вернул 1 статус выхода
make: * [hw02vector] Ошибка 1

Ответы [ 2 ]

7 голосов
/ 09 мая 2011

Идет ошибка компоновщика, потому что для классов template определение должно быть всегда видимым Либо вы можете переместить все содержимое vector.cc в vector.h. Или вы можете просто включить vector.cc везде, где вы включаете vector.h.

примечание :

Следующие строки в вашем .h файле не помогают:

#ifndef VECTOR__HH__
#define VECTOR__HH_

делает оба макроса похожими, например, VECTOR__HH. Эти макросы используются, чтобы избежать многократного включения файлов.

5 голосов
/ 09 мая 2011

При программировании шаблонов определение функций должно быть видно там, где определен шаблон класса.Обычно это делается путем определения функций внутри самого класса.

Таким образом, вы можете решить вашу проблему двумя способами:

  • Переместите все определения с vector.cpp на * 1009.* (что на самом деле является обычным решением).И удалите Vector.cpp, поскольку он не нужен.
  • Или включите файл vector.cpp в конце файла vector.hh после определения шаблона класса Vector, например:

    #ifndef VECTOR__HH__
    #define VECTOR__HH__  //<--- corrected this also!
    
    template<class T> 
    class Vector {
       //...
    };
    
    //...
    
    #include "vector.cpp"
    
    #endif VECTOR__HH__
    
...