0

C ++でのポインターの使用に問題があり、それが何であるかを理解できません。

LectureNodeというクラスがあります。

class LectureNode
{
public:
Lecture *LecturePtr;

LectureNode(Lecture lec)
{
    LecturePtr = &lec;
}
};

このクラスのコンストラクターは問題なく機能します。私は別のクラスを持っています:

class LectureForest
{
LectureNode *LecNode;
list<Lecture>::iterator it;

public:
LectureForest(list<Lecture> lecs)
{
    Makeset(lecs);
}

void Makeset(list<Lecture> lecs)
{
    for(it = lecs.begin(); it != lecs.end(); it++)
    {
        LecNode = LectureNode(*it); 
    }
}

この最後の行で問題が発生します。(* it)はLectureNodeコンストラクターに渡され、LectureNodeは正常に作成されますが、LecNodeはそれをポイントせず、代わりにデバッガーが不正なポインターを示します。

ありがとうございました。

4

1 に答える 1

8

1つの問題、コード

LectureNode(Lecture lec)
{
    LecturePtr = &lec;
}

値による引数、ローカルへのポインタを格納します。そのポインタが後で使用される場合、値による引数がもう存在しないため、未定義動作になります。


合理的な解決策の1つは、

LectureNode(Lecture* const lec)
    : lecturePtr_( lec )
{}

どこ

  • ポインタを渡すこと。これは、ポインタを格納するときに従来どおりです(また、UBの問題も解決します)。

  • コンストラクター本体での割り当ての代わりに初期化子リストを使用することは、良い習慣です(より一般的で、より多くの場合に機能し、より効率的になる可能性もあります)

  • lec統一命名規則(との両方に小文字の頭文字lecturePtr_)を使用し、データメンバーに共通の接尾辞規則(最後にアンダースコア)を使用します。


ちなみに、「初期化子リスト」という用語には複数の意味があります。また、初期値の中括弧リストも参照します。コンストラクタ初期化子リストの聖なる標準の用語はmem-initializerですが、私はその用語を使用している人を聞いたり見たりしたことがありません。

于 2013-01-13T16:25:16.783 に答える