c++复制构造函数的奇怪行为
C++ Copy Constructor Strange Behavior
给定以下代码:
class monomial {
public:
mp_real coe;
int exp;
monomial *next;
};
class polynomial
{
private:
monomial *start;
public:
polynomial();
~polynomial();
void destroy_poly(monomial *);
polynomial & operator=(const polynomial &);
polynomial(const polynomial&);
monomial * get_start();
};
polynomial::polynomial() {
start = NULL;
}
polynomial::~polynomial() {
if (start != NULL) {
destroy_poly(start);
}
start = NULL;
}
void
polynomial::destroy_poly(monomial * m) {
monomial * cm = m;
if (cm->next != NULL) {
destroy_poly(cm->next);
}
delete m;
}
polynomial::polynomial(const polynomial& p) {
if (p.start != NULL) {
start = new monomial();
start->coe = p.start->coe;
start->exp = p.start->exp;
monomial * tmpPtr = p.start;
monomial * lastPtr = start;
while (tmpPtr->next != NULL) {
monomial * newMon = new monomial();
newMon->coe = tmpPtr->next->coe;
newMon->exp = tmpPtr->next->exp;
lastPtr->next = newMon;
lastPtr = lastPtr->next;
tmpPtr = tmpPtr->next;
}
}
}
polynomial & polynomial::operator=(const polynomial &p) {
if (p.start != NULL) {
start = new monomial();
start->coe = p.start->coe;
start->exp = p.start->exp;
monomial * tmpPtr = p.start;
monomial * lastPtr = start;
while (tmpPtr->next != NULL) {
monomial * newMon = new monomial();
newMon->coe = tmpPtr->next->coe;
newMon->exp = tmpPtr->next->exp;
lastPtr->next = newMon;
lastPtr = lastPtr->next;
tmpPtr = tmpPtr->next;
}
}
return *this;
}
然后在main.cpp:
main() {
polynomial poly;
// code that initializes / sets values for
// various monomials pointed to by poly.start.
map<set<unsigned int>, polynomial> hash;
set<unsigned int> tmpSet;
tmpSet.insert(0);
hash[tmpSet] = poly;
}
我可以在复制构造函数的第一行设置一个断点,在我跳过哈希[tmpSet] = polyline之后,复制构造函数中的p.start为NULL。然后,它被第二次调用,此时p.start内部设置了奇怪的值。
知道发生了什么事吗?
谢谢,Erich
编辑1:本以为在多项式类中添加赋值操作符可以解决这个问题,但事实并非如此。还是有同样的问题
你违反了三原则:
由于重载了复制构造函数,因此应该重载复制赋值操作符和析构函数。
两个问题
1)你没有一个无参数的构造函数,所以编译器在它认为合适的情况下归档初始值。p.start初始值为NULL的事实是
2)当复制构造函数用p.start == NULL
传递polynomial
时,您不会初始化该类中的任何变量,因此下一个复制可以具有编译器分配的任何初始值(参见问题#1)。
您应该添加一个默认构造函数,将start初始化为NULL。
正如al指出的那样,你违反了三原则。看,当你把东西放进容器时指针会发生什么变化
monomial *start;
monomial *next;
如果p.start == NULL,则复制构造函数将start设置为某个随机值。这可能是问题的原因,这取决于程序中的其他代码。此外,您没有赋值操作符,因此编译器正在为您进行浅复制。你必须添加另一个功能polynomial &operator=(const polynomial& b)
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 复制构造函数、赋值运算符C++
- std::ofstream 作为类成员删除复制构造函数?
- 复制构造函数C++无法正确复制指针
- 关于复制构造函数的一个棘手问题
- 为什么调用复制构造函数而不是移动构造函数?
- 填充上编译器生成的复制构造函数之间的不一致
- C++ 对象指针数组的复制构造函数
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 防止在复制构造函数中隐式调用基构造函数
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 具有已删除移动和复制构造函数的类的就地构造
- 复制构造函数隐式转换问题
- 复制构造函数中的递归调用