2016-06-23 3 views
0

私は教育の目的でカスタムVectorクラスを作成していますが、演算子+を正しく取得できません。値を返す直後にブレークポイントがトリガされますが、なぜ、デストラクタやコンストラクタなのか分かりませんが、わかりません。私の演算子+カスタムVectorクラスの何が問題になっていますか?

operator+Vector<T>の代わりにTに変更し、​​を返すと、プログラムが正常に動作します。だから私は、問題がコンストラクタ/デストラクタから来ていると思ったのです。ここ

#include <initializer_list> 
#include <functional> 

typedef size_t SIZE; 

template <class T> 
class Vector { 
private: 
    SIZE _sz; 
    T *_els; 
public: 

    typedef std::function<void(Vector*)> sorting_function; 

    static const void populateVector(Vector*, const SIZE&, typename Vector<T>::sorting_function, const bool& sameLength = false); 

    Vector(SIZE sz = 0) : _sz(sz), _els(nullptr) {} 
    Vector(SIZE, const T&); 
    Vector(std::initializer_list<T>); 
    Vector(const Vector&); 
    Vector(Vector&& vec) : _sz(vec._sz), _els(vec._els) { delete[] vec._els; } 

    ~Vector() { delete[] _els; } 

    Vector& operator=(const Vector&); 
    Vector& operator=(Vector&&); 
    Vector& operator=(std::initializer_list<T>); 
    Vector operator+(const Vector&); 

    SIZE size() const { return _sz; } 
    T* elems() const { return _els; } 

    int *begin() { return &_els[0]; } // for (auto i : Vector) {} 
    int *end() { return &_els[_sz]; } // 
}; 

そして、私の関連部分Vector.cpp

#include <stdexcept> 
#include "Vector.h" 


template <class T> 
Vector<T>::Vector(const Vector& vec) { 
    cout << "Vector initializer" << endl; 
    if (this != &vec) { 
     populateVector(this, vec._sz, [&](Vector<T>* obj) { 
      for (SIZE i = 0; i < vec._sz; i++) 
       obj->_els[i] = vec._els[i]; 
     }); 
    } 
} 

template <class T> 
Vector<T>& Vector<T>::operator=(const Vector<T>& vec) 
{ 
    cout << "Operator = const" << endl; 
    populateVector(this, vec._sz, [&](Vector<T>* obj) { 
     for (SIZE i = 0; i < vec._sz; i++) 
      obj->_els[i] = vec._els[i]; 
    }, true); 

    return *this; 
} 

template <class T> 
Vector<T>& Vector<T>::operator=(Vector<T>&& vec) 
{ 
    cout << "Operator = move" << endl; 
    populateVector(this, vec._sz, [&](Vector<T>* obj) { 
     for (SIZE i = 0; i < vec._sz; i++) 
      obj->_els[i] = vec._els[i]; 
    }); 

    delete[] vec._els; 

    return *this; 
} 

template <class T> 
Vector<T>& Vector<T>::operator=(std::initializer_list<T> list) 
{ 
    populateVector(this, list.size(), [&](Vector<T>* obj) { 
     SIZE i = 0; 
     for (T elem : list) 
      obj->_els[i++] = elem; 
    }); 

    return *this; 
} 

template <class T> 
Vector<T> Vector<T>::operator+(const Vector<T>& vec) 
{ 
    cout << "Operator + const" << endl; 
    Vector<T> thiscpy(*this); 

    if (_sz != vec._sz) throw std::runtime_error("Vector size mismatch"); 

    for (SIZE i = 0; i < _sz; i++) 
     thiscpy._els[i] += vec._els[i]; 

    return thiscpy; 
} 

template <class T> 
const void Vector<T>::populateVector(Vector<T>* obj, const SIZE& newsize, typename Vector<T>::sorting_function repopf, const bool& sameLength = false) 
{ 
    cout << "Pupulate vector" << endl; 
    if (sameLength && (obj->_sz != newsize)) throw std::runtime_error("Incompatible vector length"); 

    obj->_sz = newsize; 
    try 
    { 
     if (obj->_els != nullptr) delete[] obj->_els; 
     obj->_els = new T[newsize]; 

     repopf(obj); 
    } 
    catch (const std::exception& e) 
    { 
     obj->_sz = 0; 
     obj->_els = nullptr; 
     throw std::runtime_error("Couldn't populate vector"); 
    } 
} 

そしてmain.cppに

とにかく、ここでは関係Vector.hの一部は次のとおりです。

int main() { 

    Vector<int> v1{ 1,2,3,4 };  //Vector<T>::Vector(std::initializer_list<T>); 
    Vector<int> v2{ 2,4,8,16 }; //Vector<T>::Vector(std::initializer_list<T>); 

    try 
    { 
     cout << "----------" << endl; 
     v1 + v2;      //Triggers breakpoint 
     cout << "----------" << endl; 
     cout << "done" << endl; 
    } 
    catch (const std::exception& e) 
    { 
     cout << e.what() << endl; 
    } 

    cin.get(); 
    return 0; 
} 

、プログラムの出力

Pupulate vector 
    Pupulate vector 
    ---------- 
    Operator + const 
    Vector initializer 
    Pupulate vector 
+0

*しかし、私はなぜ、デストラクタかコンストラクタであるのかわかりません* - あなたはこの単純ではないコードをすべて書きましたが、あなたが書いたコードのデバッグ方法はわかりません。 – PaulMcKenzie

+3

移動コンストラクタで、なぜあなたは '[vec_els;]を削除しますか? – TerraPass

+1

@πάνταῥεῖいいえ、あなたは 'operator + ='を考えています。 – ecatmur

答えて

2

あなたのコピーコンストラクタがelspopulateVectorを呼び出すに初期化したことがないので、それはnullptrされない場合があります(それもあるかもしれない)、あなたは何にdelete[]を呼んでいますメンバーポインタの内容はです。これは未定義の動作につながります。

+2

また、スマートポインタは理由があります。 'delete'を呼び出すタイミングがわからない場合は、それらを使用してください。 –

関連する問題