1

より有能な C++ プログラマーになるために、参照を使用して実験しています。これまで、Objective-C の場合のように、オブジェクトを参照するときは通常、ポインターを使用していました。

だから私はTermオブジェクトのリストを格納するPolynomialクラスをプログラミングしてきました

(TermNode* termHead,termTail)

しかし、リストされている最初の実装を使用して用語をリストに追加しようとすると、用語の追加で Term のコンストラクターを呼び出すと、以前に作成された Term ノードの Term& 参照が上書きされます。コンストラクタ。

リストされた最初の実装について、異常な動作を引き起こす技術的な問題は何ですか? 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 に答える