2

私は宿題のために自分の抽象クラス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
):collect2への未定義の参照'Vector<int>::push_back(int const&)'
:ldが返されました1終了ステータス
make:* [hw02vector]エラー1

4

2 に答える 2

7

templateクラスの場合、定義は常に表示されている必要があるため、リンカエラーが発生します。vector.ccのすべてのコンテンツをに移動できますvector.h。または、含めるvector.cc場所に単純に含めることができますvector.h

サイドノート

.hファイルの次の行は役に立ちません。

#ifndef VECTOR__HH__
#define VECTOR__HH_

、などの両方のマクロを類似させますVECTOR__HH。このマクロは、ファイルが複数含まれないようにするために使用されます。

于 2011-05-09T06:21:37.480 に答える
5

テンプレートプログラミングでは、関数の 定義は、クラステンプレートが定義されている場所に表示される必要があります。これは通常、クラス自体の内部で関数を定義することによって行われます。

したがって、問題を解決する方法は2つあります。

  • すべての定義をからvector.cppに移動しますvector.hh(これは実際には通常の解決策です)。そしてVector.cpp、不要なので削除します。
  • または、次のように、クラステンプレートの定義後、ファイルvector.cppの最後にファイルを含めます。vector.hhVector

    #ifndef VECTOR__HH__
    #define VECTOR__HH__  //<--- corrected this also!
    
    template<class T> 
    class Vector {
       //...
    };
    
    //...
    
    #include "vector.cpp"
    
    #endif VECTOR__HH__
    
于 2011-05-09T06:19:55.390 に答える