我已经创建了一个对象和一个存储库。 当我尝试将对象插入到存储库中(使用我创建的insert函数)时,出现编译错误。
我要插入存储库中的类
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);
}
在主要功能中,我有
char c[] = "some characters";
Payment pay = Payment(7,9,c);
Repository rep = Repository();
rep.insert(pay);
运行程序时出现错误“ 表达式:_CrtlsValidHeapPointer(block)“
答案 0 :(得分:0)
由于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;
}
以上内容在赋值运算符中使用copy/swap idiom。复制构造函数使用成员初始化列表。
析构函数不需要检查null指针,因为删除nullptr是完全有效的。
答案 1 :(得分:0)
现在添加到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>
库学习太多东西,所以我必须仔细研究一下。祝你好运! ^ _ ^