1

为了成为一名更有能力的 C++ 程序员,我正在尝试使用引用。过去,我通常在引用对象时使用指针,例如在 Objective-C 中。

所以我一直在编写一个存储Term对象列表的多项式

(TermNode* termHead,termTail)

但是,当我尝试使用列出的第一个实现将术语添加到列表中时,在 add term 中调用 Term 上的构造函数时,会覆盖先前创建的 Term 节点中的 Term& 引用,就好像它使用了上一次调用中的this指针构造函数。

列出的第一个实现在技术上存在什么问题,导致其行为异常?即使我没有更改 TermNode 的结构,它也仅在我使用指针和new时才有效。

struct TermNode {
    Term& value;
    TermNode* next;
};

Term::Term(int coefficient,int firstTermDegrees,int secondTermDegrees) {
        this->coefficient = coefficient;
        this->xDegree = firstTermDegrees;
        this->yDegree = secondTermDegrees;
    }

//Doesn't work
void Polynomial::addTerm(int coefficient, int xDegree, int yDegree) {
    Term term(coefficient,xDegree,yDegree);
    addTerm(term);
}

void Polynomial::addTerm(Term& term) {
    TermNode* t = new TermNode{term,nullptr};
    if(isEmpty())
    {
        termHead = t;
        termTail = t;
    }
    else
    {
        termTail->next = t;
        termTail = termTail->next;
    }

}

//Does work
void Polynomial::addTerm(int coefficient, int xDegree, int yDegree) {
    Term* term = new Term(coefficient,xDegree,yDegree);
    addTerm(term);
}

void Polynomial::addTerm(Term* term) {
    TermNode* t = new TermNode{*term,nullptr};
    if(isEmpty())
    {
        termHead = t;
        termTail = t;
    }
    else
    {
        termTail->next = t;
        termTail = termTail->next;
    }

}

bool isEmpty() {
return nullptr == termHead;
}
4

2 回答 2

3
//Doesn't work
void Polynomial::addTerm(int coefficient, int xDegree, int yDegree)
{
    Term term(coefficient,xDegree,yDegree);//here you created automatic object
    addTerm(term);                         //it will be deleted in next line
}                                    //it is an error to call addTerm(Term& term)

这行得通

//Does work
void Polynomial::addTerm(int coefficient, int xDegree, int yDegree)
{
    Term* term = new Term(coefficient,xDegree,yDegree);
    addTerm(term);
}

因为在这里您在免费商店中创建了对象。它的寿命会延长,直到您调用delete它(旁注:delete在某处调用,此时您有内存泄漏!或使用智能指针),所以这很好用。

void Polynomial::addTerm(Term* term)
{
    TermNode* t = new TermNode{*term,nullptr};
    // ...
}

您可以使用引用,但以它们应该使用的方式。当它被实际删除时,您不能使用对临时的引用。但是,您可以将临时对象绑定到 const 引用,但由于您的结构定义

struct TermNode
{
    Term& value;
    TermNode* next;
};

在构造函数中,您再次获取引用,因此在这种情况下将临时绑定到 const 引用将再次导致分段错误。

于 2013-11-03T00:13:44.337 回答
1

在第一个实现中,您传递对在方法 addTerm 结束时销毁的临时对象的引用。

于 2013-11-03T00:12:23.110 回答