2013-03-23 94 views
1

所以,基本上,我正在做一个家庭作业,我有一个链表与多项式系数和指数。当不包含复制c-tor时,退出main(析构函数)时代码会崩溃。使用复制c-tor不会发生,但我想知道为什么'因为我没有明确地在任何地方调用复制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时,它正常工作。

+1

如果您不打算调用copy-ctor或支持它,则可以通过C++ 11的语法('CPList(const CPList&)= delete;')将其删除或声明它作为'private:'。这样做会立即告诉你这个问题根源在哪里。如果没有一个有效的* copy-ctor来为具有动态成员的类授予[Rule of Three/Five](http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)),那么迟早会像这样绑定自己的软管。 – WhozCraig 2013-03-23 03:23:23

回答

1

p1p2都按值传递到mul,所以当mul返回时创建副本并将其销毁。

+0

对,我不知道我是如何忽视这一点的。谢谢。 – rndm 2013-03-23 03:19:23

0
CPList* CPList :: mul (CPList p1, CPList p2) {//code} 

当你按值传递和haven`t实现默认的拷贝构造函数 - 浅拷贝创建对象(这意味着成员的所有值都只是复制)
简单(的
内置类型)是罚款),
但如果你在课堂成员像指针或引用& *然后它们的值复制,这​​是不是很好,因为:
例如:

class A 
{ 
A(){new m_pOnInt}; 
~A(){delete m_pOnInt}; 
int* m_pOnInt; 
} 

void someFunction(A objA); 

当你调用someFunction(objA) - 创建一个所提供的实例的临时副本并推入堆栈,
后功能控制权返回给调用函数的析构函数调用在堆栈中的所有对象,所以〜objA ()被调用; 但你仍然有类A的实例,你提供了作为someFunction的参数,但是使用非有效的m_pOnInt作为删除操作符应用于它,所以当你调用例如A的析构函数时出现问题

解决方案的使用“规则3”:它说当你处理复杂的对象时(包含指针/引用的成员 - 实现特殊的成员函数:拷贝构造函数,赋值操作符,构造函数,它允许你执行深度拷贝。