Получить «Ошибка точки останова при удалении» при использовании шаблона - PullRequest
0 голосов
/ 05 ноября 2019

Я пользуюсь visual studio.

У меня 3 класс. Это нормально, когда я пытаюсь напечатать Rectangle ABCD , но когда я помещаю ABCD в Array [rectangle] A и пытаюсь снова напечатать ABCD, появляется сообщение "wntdll.pdb не загружен" ия продолжаю, это " вызывает ошибку точки останова !! " в delete в ~ Rectangle ()

Я знаю, что это что-то до указателя в классе Rectangle, но может 'т. вне.

`int main(){
    Array<Rectangle>A;
    Rectangle a;
    cout << a;     //It's oke
    A.PushBack(a); // problem here
    cout<<a;
}`
    class Point
    {
    private:
       float _x;
       float _y;
    public:
       float GetX() { return _x; }
       float GetY() { return _y; }
    public:
       Point();
       Point(float, float);
       Point(const Point&);
       ~Point() {};
    public:
       string ToString() const;
    public:
       friend istream& operator>>(istream&, Point*);
       friend ostream& operator<<(ostream&, const Point&);
    };
    Point::Point() {
       _x = 1;
       _y = 1;
    }
    Point::Point(float x, float y) {
       _x = x;
       _y = y; 
    }
    Point::Point(const Point& a) {
       _x = a._x;
       _y = a._y;
    }
    string Point::ToString() const{
       stringstream out;
       out << "( " << _x << "," << _y << " )";
       return out.str();
    }
    istream& operator>>(istream& in, Point* a) {
       cout << "Nhap x: ";
       in >> a->_x;
       cout << "Nhap y: ";
       in >> a->_y;
       return in;
    }
    ostream& operator<<(ostream& out, const Point& a)
    {
       out << a.ToString();
       return out;
    }
    ```


class Rectangle
{
private:
    Point* _topleft;
    Point* _botright;
public:
    void Set_topleft(Point tl) { _topleft = &tl; }
    Point Get_topleft() { return *_topleft; }
    void Set_botright(Point br) { _botright = &br; }
    Point Get_botright() { return *_botright; }
public:
    Rectangle();
    Rectangle(Point*, Point*);
    ~Rectangle();
public:
    string ToString() const;
public:
    friend istream& operator>>(istream&, Rectangle&);
    friend ostream& operator<<(ostream&, const Rectangle&);
};
Rectangle::Rectangle()
{
    _topleft = new Point(0, 2);
    _botright = new Point(3, 0);
}
Rectangle::Rectangle(Point* a, Point* b)
{
    _topleft = new Point(*a);
    _botright = new Point(*b);
}
Rectangle::~Rectangle()
{
    delete _topleft;
    delete _botright;
}
string Rectangle::ToString() const
{
    stringstream out;
    out << "A" << *_topleft << "+" << "D" << *_botright;
    return out.str();
}
istream& operator>>(istream& in, Rectangle& a)
{
    std::cout << "A( x,y ): ";
    in >> a._topleft;
    std::cout << "D( x,y ): ";
    in >> a._botright;
    return in;
}
ostream& operator<<(ostream& out, const Rectangle& a)
{
    out << a.ToString();
    return out;
}
```
    template<class T>
    class Array
    {
    private:
        T* _a;
        int _len;
    public:
        Array();
        ~Array();
    public:
        int length() { return _len; }
        void PushBack(T);
        T GetAt(int);
    };
    template<class T>
    Array<T>::Array() {
        _a = new T[128];
        _len = 0;
    }
    template<class T>
    Array<T>::~Array() {
        delete[] _a;
        _len = 0;
    }
    template<class T>
    void Array<T>::PushBack(T value) {
        if (_len >= 128)
        {
            std::cout << "Array is over size, which is 128\n";
            return;
        }
        _a[_len] = value;
        _len++;
    }
    template<class T>
    T Array<T>::GetAt(int pos) {
        return _a[pos];
    }

    ```



1 Ответ

2 голосов
/ 05 ноября 2019

Проблема в вашем коде состоит в том, что когда вы PushBack объект Rectangle a в массиве, вы создаете копию этого объекта. Это означает, что вы просто копируете указатели _topleft и _botright. Таким образом, в этой части кода у вас есть 2 объекта с одинаковыми указателями, поэтому вы пытаетесь delete удвоить одну и ту же часть памяти. Чтобы это исправить, вам нужно определить собственный конструктор копирования, который будет создавать новые указатели в новом объекте.
Не забудьте также определить собственные конструкторы перемещения или отключить его для вашего класса.

Rectangle(const Rectangle &other) 
 {
        if(other._topleft)
           _topleft= new Point(*other._topleft); 
        else
            _topleft = nullptr;
        if(other._botright)
           _botright= new Point(*other._botright); 
        else
            _topleft = nullptr;
 } 

Следующийпроблема из-за определения void Array<T>::PushBack(T value). Пожалуйста, измените его на void Array<T>::PushBack(const T& value). Также попробуйте Rectangle(Rectangle&& o) = delete;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...