所以,基本上,我正在做一个家庭作业,我有一个带有多项式系数和指数的链表。当不包括复制c-tor时,代码在退出main(析构函数)时崩溃。有了复制程序,它并没有发生,但我想知道为什么导致我没有明确地称之为复制c-tor。这只是代码的一部分。 Coef函数在列表中添加了参数exp和coef的节点,因此我认为不需要包含它。
CPList :: ~CPList ()
{
while (!isEmpty())
deleteFromHead();
}
void CPList :: deleteFromHead ()
{
CPNode* tmp=head;
if (head==tail)
head=tail=NULL;
else head=head->next;
delete tmp;
}
CPList* CPList :: mul (CPList p1, CPList p2)
{
CPList* res = new CPList;
CPNode *first, *second;
for (first=p1.head; first!=NULL; first=first->next)
for (second=p2.head; second!=NULL; second=second->next)
res->coef(first->exp+second->exp, first->coef*second->coef);
res->check();
return res;
}
在此代码之后,它在关闭的括号内崩溃。
int main ()
{
...
ptr=p3.mul(p1, p2);
ptr->printall();
}
包含复制c-tor时,它正常工作。
答案 0 :(得分:1)
p1
和p2
都按值传递到mul
,因此副本会在mul
返回时创建然后销毁。
答案 1 :(得分:0)
CPList* CPList :: mul (CPList p1, CPList p2) {//code}
当你通过值并且没有实现默认的复制构造函数时 - 创建了对象的浅拷贝(这意味着只复制了所有成员的值)
对于简单(内置类型),很好),
但如果您在课堂上有成员,如指针或引用& *,那么他们的值会被复制,因为:
例如:
class A
{
A(){new m_pOnInt};
~A(){delete m_pOnInt};
int* m_pOnInt;
}
void someFunction(A objA);
当你调用someFunction(objA)时 - 创建提供的A实例的临时副本并将其推入堆栈,
函数返回控制到调用函数后,对堆栈中的所有对象调用析构函数,因此调用~objA();
但你仍然有你作为someFunction的参数提供的A类实例,但是由于删除操作符被应用于非有效的m_pOnInt,所以当调用A的析构函数时你遇到了问题
解决方案使用“3的规则”:这表示当你处理复杂的对象(包含指针/引用等成员的东西)时,实现特殊的成员函数:复制构造函数,赋值运算符,构造函数,允许您执行深层复制。