web-dev-qa-db-ja.com

C ++:メンバーポインターをnullに初期化しますか?

私は次のようなクラスを持っています:

class Foo
{
public:
    Foo();
    virtual ~Foo();

private:
    Odp* bar;
};

barNULLに初期化したい。これはそれを行うための最良の方法ですか?

Foo::Foo() : bar(NULL)
{
}

また、デストラクタは仮想である必要がありますか? (それが真の場合、コンストラクタも仮想でなければなりませんか?)

32
Nick Heiner

barNULLに初期化したい。これはそれを行うための最良の方法ですか?

正しい方法です。あ、はい。

また、デストラクタは仮想である必要がありますか?

いいえ。デストラクタは、Fooクラスから継承し、Fooポインタを使用してそれらの派生クラスを削除する場合にのみ仮想である必要があります(一般的な経験則として、他の仮想メンバーがある場合は、仮想である必要があります)。

(それが真の場合、コンストラクタも仮想でなければなりませんか?)

いいえ。コンストラクタはneedvirtualになることもcanになることもありません。

40
greyfade
  1. はい、初期化リストが最適です。

  2. 多分。デストラクタは、クラスに他の仮想関数を含める場合、またはクラスを継承する場合(通常はこれらが一緒に実行されます)、仮想である必要があります。

  3. いいえ。C++で仮想コンストラクタを使用することはできません。 (意味とはどういう意味ですか?)

あなたの質問の性質は、virtualキーワードが何をするのか、または何のためにあるのか本当に理解しておらず、他の場所やチュートリアルで見たものを単にコピーしていることを示唆しています。あなたが書いているコードのallの目的を理解するのが最善です。ここから始めるかもしれません: http://www.parashift.com/c++-faq-lite/virtual-functions.html

10
Tyler McHenry

4つの異なる方法があります。どれが一番いいかはあなた次第です

Foo::Foo() : bar() // value initialization
{
}

Foo::Foo() : bar(0) // direct null pointer constant
{
}

Foo::Foo() : bar(NULL) // null pointer constant by macro
{
}

Foo::Foo() : bar(nullptr) // pointer literal of type std::nullptr_t
{
}
  1. はい
  2. デストラクタが仮想であるという2番目の質問については、 http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7 短い回答を参照してください。あなたの場合、デストラクタが必須である必要はありません。
  3. 仮想コンストラクタなどはありません。
4
bits

考慮すべきもう1つのオプションは、生のポインターの代わりに、スマートポインタークラス(boost::scoped_ptrboost::shared_ptr、C++ 0xのunique_ptrなど)を使用することです。スマートポインターのコンストラクターは、他の明示的な初期化が必要ない場合、NULLのような何かに初期化されることを確認します。スマートポインタは、ポイントされたオブジェクトが確実に破棄されるようにします。

アイテムに適切なスマートポイントポリシーの種類を決定し、それに応じて選択するだけです(さまざまな落とし穴を認識している限り、auto_ptrでも生のポインターよりも優れている場合があります)。

3
Michael Burr

1、はい

2、誰かがあなたのクラスから派生し、基本クラスへのポインタを使用できるようにしたい場合にのみ-とにかくdtorを仮想化する

3、いいえ、あなたは仮想俳優を持つことはできません(またはすべての俳優が私が仮定する仮想ですか?)

2
Martin Beckett

仮想関数は、実行時にクラスのどの関数(基本クラスと派生クラスの両方で定義されている)を呼び出す必要があるかを決定します。しかし、オブジェクトが作成されると、コンパイラーは呼び出されるコンストラクターを認識します。たとえば。基本オブジェクトが作成されると、基本コンストラクターが呼び出され、派生クラスと同じです。したがって、コンストラクターを仮想化しても意味がありません。ルックアップテーブルvtableを使用してのみ解決できるため、デストラクタは仮想である必要があります。

0
Priji