Ошибка вставки нового объекта в репозиторий - PullRequest
0 голосов
/ 24 марта 2019

Я создал объект и репозиторий для него.Когда я пытаюсь вставить объект в репозиторий (с созданной мной функцией вставки), я получаю ошибку компиляции.

Класс, который я пытаюсь вставить в репозиторий

class Payment{
private:
    int day;
    int amount;
    char *type;

public:
    Payment();
    Payment(int day, int amount, char *type);
    Payment(const Payment &p);
    ~Payment();

    //getters
    int getDay()const;
    int getAmount()const;
    char* getType()const;

    //setters
    void setDay(int day);
    void setAmount(int amount);
    void setType(char* type);

    //operator
    Payment& operator=(const Payment& other);
    friend ostream& operator<<(ostream &os,const Payment &obj);
};

//copy constructor
Payment::Payment(const Payment & p){
    this->day = p.day;
    this->amount = p.amount;
    if(this->type!=NULL)
        delete[] this->type;
    this->type = new char[strlen(p.type)+1];
    strcpy_s(this->type, strlen(p.type) + 1, p.type);
}

//assignment operator
Payment& Payment::operator=(const Payment &other) {
    this->day = other.day;
    this->amount = other.amount;
    this->type = new char[strlen(other.type) + 1];
    strcpy_s(this->type, strlen(other.type) + 1, other.type);
    return *this;
}

//destructor
Payment::~Payment(){
    this->day = 0;
    this->amount = 0;
    if (this->type != NULL) {
        delete[]this -> type;
        this->type = NULL;
    }
}


//Repository header
class Repository{
private:
    vector<Payment> list;
public:
    Repository();

    int getLength();

    void insert(const Payment& obj);
    void remove(int position);
};

//Repository cpp
Repository::Repository(){
    this->list.reserve(10);
}

//return the size of the list
int Repository::getLength() {
    return this->list.size();
}

//add payment to list
void Repository::insert(const Payment &obj) {
    this->list.emplace_back(obj);
}

//remove payment from list
void Repository::remove(int position) {
    this->list.erase(this->list.begin() + position);
}

InОсновная функция у меня

char c[] = "some characters";
Payment pay = Payment(7,9,c);
Repository rep = Repository();
rep.insert(pay);

Когда я запускаю программу, я получаю сообщение об ошибке «Выражение: _CrtlsValidHeapPointer (block)» *

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

Теперь добавление к std::vector работает хорошо, без каких-либо ошибок во время выполнения (с помощью опубликованного кода @PaulMcKenzie).Я также нашел пример кода, который работает, где только оператор присваивания немного отличается.Конвертируется в мой код будет (и он тоже работает):

Payment& Payment::operator=(const Payment &other) {
    if (this != &other) {
        this->setDay(other.day);
        this->setAmount(other.amount);
        this->setType(other.type);
    }
    return *this;
}

Спасибо за помощь!Теперь работает отлично!Из библиотеки <algorithm> мне не удавалось много учиться, поэтому мне придется присмотреться.Желаю тебе удачи!^ _ ^

0 голосов
/ 27 марта 2019

Поскольку std::vector будет копировать, std::vector<Payment> требует, чтобы Payment имел правильную семантику копирования.Ваш конструктор копирования и оператор присваивания не реализованы правильно.Оператор присваивания вызывает утечки памяти, так как вам не удалось delete [] существующей памяти.

Самым простым решением является удаление с использованием члена char *type; и просто использование std::string type;.Тогда класс Payment будет иметь правильную семантику копирования автоматически.


Учитывая, что поправки к вашему классу Payment приведены ниже:

#include <algorithm>
//...
Payment::Payment() : day(0), amount(0), type(nullptr) {}

Payment::Payment(const Payment & p) : day(p.day), amount(p.amount), type(nullptr)
{
    if ( p.type )
    {
        type = new char[strlen(p.type) + 1];
        strcpy_s(this->type, strlen(p.type) + 1, p.type);
    }
}

// Use the copy/swap idiom    
Payment& Payment::operator=(const Payment &other) 
{
    Payment temp(other);  // make a temporary copy
    // swap out contents of temporary with this object
    std::swap(temp.day, day);  
    std::swap(temp.amount, amount);
    std::swap(temp.type, type);
    return *this;  
 }  // when this brace has been reached, the temp copy dies off with the old data

Payment::~Payment()
{
   delete [] type;
}

Выше используется идиома копирования / обмена в операторе присваивания.Конструктор копирования использует список инициализации члена.

Деструктору не нужно проверять нулевой указатель, поскольку удаление nullptr совершенно допустимо.

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