1

所以我试图定义一个模板类“TwoWayVector”和“TwoWayVectorIterator”,但我遇到了很多问题。我想在 TwoWayVector 中定义 == 以返回引用并将 const TwoWayVector 作为参数,这就是我定义其他运算符的方式,而 g++ 没有抱怨,但由于某种原因,下面的代码会产生错误

TwoWayVector.cc: In member function ‘bool& TwoWayVector<T>::operator==(TwoWayVector<T>)         [with T = int]’:
Test.cc:10:   instantiated from here
TwoWayVector.cc:40: error: passing ‘const TwoWayVector<int>’ as ‘this’ argument of ‘T&       TwoWayVector<T>::operator[](int) [with T = int]’ discards qualifiers
Test.cc:10:   instantiated from here
TwoWayVector.cc:32: warning: reference to local variable ‘result’ returned

测试.cc

#include <iostream>
#include "TwoWayVector.cc"
int main(){
TwoWayVector<int> numbers;
TwoWayVector<int> numbers2;
numbers.push_back(3);
numbers.push_back(2);
numbers2.push_back(3);
numbers2.push_back(2);
cout << (numbers==numbers2);
cout << endl;
return 0;
}

双向矢量.cc

using namespace std;
#include "TwoWayVectorIterator.cc"
template <class T> class TwoWayVector{
public:

T* data;
int capacity;
int nextFree;

TwoWayVector(){
    capacity = 10;
    nextFree = 0;
    data = new T[capacity];
}

~TwoWayVector(){
    delete data;
}

T& operator[](const int index){
    if( index >= capacity || capacity + index < 0){
        string number = static_cast<ostringstream*>( &(ostringstream() << index) )->str();
        string error = "index " + number + " is out of bounds";
        throw error;
    }
    else if(index < 0){
        return data[nextFree+index];
    }
    return  data[index];
}
bool& operator==(const TwoWayVector vector2){
    bool result = true;
    if(capacity != vector2.capacity){
        result = false;
    }
    if(nextFree != vector2.nextFree){
        result = false;
    }
    for(int i=0; i<nextFree ; i++){
        if(data[i] != vector2[i]){
            result = false;
        }
    }
    return result;
}
 //memory leaks?
void push_back(T object){
    if(capacity <= nextFree){
        capacity = capacity*2;
        T* tmp = new T[capacity];
        for(int i=0; i<capacity; i++){
            tmp[i] = data[i];
        }
        delete data;
        data = tmp;
    }
    data[nextFree] = object;
    nextFree++;
}

T pop_back(){
    nextFree--;
    T result = data[nextFree];
    data[nextFree] = NULL;
    return result;
}

int size(){
    return nextFree;
}

TwoWayVectorIterator<T>* begin(){
    TwoWayVectorIterator<T>* i = new TwoWayVectorIterator<T>(0,this);
    return (i);
}
TwoWayVectorIterator<T>* end(){
    TwoWayVectorIterator<T>* i = new TwoWayVectorIterator<T>(nextFree,this);
    return(i);
}

};

TwoWayVectorIterator.cc

#include <sstream>

using namespace std;

template<typename T> class TwoWayVector;

template <class T> class TwoWayVectorIterator{
public:
TwoWayVector<T>* vector;
int currentPosition;
TwoWayVectorIterator(TwoWayVector<T>& vec){
    currentPosition = 0;
    vector = vec;
}
TwoWayVectorIterator( int pos , TwoWayVector<T>* vec){
    currentPosition = pos;
    vector = vec;
}

bool& operator==(const TwoWayVectorIterator vector2){
    bool contents, position;
    contents = (vector == vector2) ? true : false;
    position =(currentPosition == vector2->currentPosition) ? true : false;
    return (contents && position);
}

bool& operator!=(const TwoWayVectorIterator vector2){
    bool contents, position;
    contents = (vector == vector2) ? false : true;
    position=(currentPosition == vector2->currentPosition) ? false : true;
    return (contents || position);
}

TwoWayVectorIterator& operator++(){
    return *this;
    currentPosition = (currentPosition+1);

}
TwoWayVectorIterator& operator++(int){
    currentPosition = (currentPosition+1);
    return *this;
}
TwoWayVectorIterator& operator=(TwoWayVectorIterator* vector2){
    &vector = vector2;
    currentPosition = vector2->currentPosition;
    return *this;
}
TwoWayVectorIterator& operator+(int n){
    currentPosition = currentPosition+n;
    return *this;
}
TwoWayVectorIterator& operator-(int n){
    currentPosition = currentPosition-n;
    return *this;
}
bool& operator<(TwoWayVectorIterator* vector2){
    return (currentPosition<vector2->currentPosition);
}
T& operator*(){
    return vector[currentPosition];
}
};

如果我将 TwoWayVector.cc 中的 == 运算符定义更改为

bool operator==(TwoWayVector vector2){
    bool result = true;
    if(capacity != vector2.capacity){
        result = false;
    }
    if(nextFree != vector2.nextFree){
        result = false;
    }
    for(int i=0; i<nextFree ; i++){
        if(data[i] != vector2[i]){
            result = false;
        }
    }
    return result;
}

然后一切都编译了,但是当我运行它时,我得到了

1
a.out(40908) malloc: *** error for object 0x7fe4f2c03b40: pointer being freed was not   allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

有任何想法吗?

4

2 回答 2

2

在内部operator==调用operator[]const 变量,它是非常量的vector2

您应该添加运算符的替代只读版本:

const T & operator[](const int index) const;

但是您应该像这样使用 object 参数的引用:

bool operator==(const TwoWayVector &vector2) const;

否则,该const关键字实际上并没有多大作用,因为它只表示您的对象副本(刚刚在堆栈上为函数创建)不能被修改,这并不重要。(因此解决此问题的最简单方法是从中删除 const 关键字,vector2但这并不完全正确。)

而且,当然,不要将 bool 值作为引用返回,因为它引用了变量result,一旦您离开函数,该变量将不再存在。

于 2013-04-13T22:04:38.047 回答
1

由于缺少复制构造函数,基本上会发生崩溃。见三法则。什么时候

bool operator==(TwoWayVector vector2){

在 main 中使用,创建了 vector 的副本,持有 numbers2 的指针,然后在退出形式 operator == 时,副本被删除,留下 numbers2 的指针指向已经释放的内存,它试图在 main() 退出时删除,这会导致错误。

于 2013-04-13T22:14:04.330 回答