2

私は C++ を使い始めたばかりで、クラ​​ス内のプライベート メンバー変数のスコープがどのように機能するかを理解するのに問題がありました。以下のコードをご覧ください

class Foo{
    private:
        std::vector<int> container;
    public:
        // other methods
};

int main(int argc, char* argv[])
{
    Foo* foo = new Foo;
    // other method calls to which foo is passed
    delete foo;
    return 0;
}

上記のコードでは、変数 "container" はプライベート メンバー変数です。「Foo」インスタンスを呼び出して、それを他のいくつかのメソッドとクラスに渡しています。以下は私の疑問です

  1. 変数「コンテナ」のスコープはどうなりますか? インスタンス foo を削除するまで、その変数は存在しますか?
  2. 「コンテナ」をベクトルへのポインタとして作成する必要がありますか?

助けてくれてありがとう

4

2 に答える 2

7
  1. はい、コンテナメンバーの有効期間は、それを含むオブジェクトが存在する限り続きます。これは、それをdelete指すポインターを呼び出すまでです(fooあなたの場合)。
  2. いいえ、そうする理由はありません。それをポインターにするにvector<int>は、有効期間を管理する必要がある動的オブジェクトを作成する必要があります (コンテナー ポインターでの削除の呼び出しを含む)。ここでは不要です。コンテナーを Foo オブジェクトと同じくらい存続させたいと仮定すると、ポインターを使用せずにコンテナーを直接格納しても問題ありません。

ポインターを渡すと、fooポインターが渡されるだけです。それが指しているオブジェクトはコピーされず、必要に応じてそれを指しているポインターのみがコピーされます。Java を知っている場合は、ポインターを渡すことは、Java でオブジェクトへの参照を渡すことと同じであると教えてください。たとえば、次のように言います。

Foo f = new Foo();
// just passes the reference (pointer in C++) to doIt. 
// the actual object is not copied
doIt(f);
于 2009-01-01T04:23:40.950 に答える
0

「Foo」インスタンスを呼び出しています

実際には、クラス Fooのインスタンスを作成しています。

具体的には、new()を介してヒープからメモリのブロックを割り当てています。このメモリ ブロックは、 Foo::containerおよびその他のオーバーヘッド クラスFooが必要とするものを格納するのに十分な大きさです。

(この例では、何もありません。他のクラスでは、追加の属性またはおそらく仮想ポインタ テーブルが存在する可能性があります。)

当然のことながら、new()は (おそらくデフォルト?) Foo::Foo()コンストラクターを呼び出します。このコンストラクターは、 std::vectorコンストラクターを介してFoo::containerを初期化します。

変数「コンテナ」のスコープはどうなりますか?

containerは、インスタンスfooの属性 [コンポーネント] です。インスタンスfooが存在する限り存在します。

スコープに関しては、Foo::containerについて話すことができます。ただし、クラスFooのインスタンスがないとFoo::constainerにアクセスできません。(例: オブジェクトfoo。) Foo::constainerは、クラスFooのインスタンスなしでは存在しません。

(1 つの値がすべてのインスタンスで共有される、多少異なる動作をするクラス変数があります。しかし、ここではそうではありません。)

この範囲指定は、公開/保護/非公開/友人のメンバー アクセス制御には関係ありません。

たとえば、一部のFoo::myPublicMethod()では、 Foo:: containerを参照できます。この状況では、明示的なスコープ設定を省略して、単にcontainerとして参照することもできます。

プライベートであるため、クラスFoo のメソッドの外でFoo::containerにアクセスすることはできません。

インスタンス foo を削除するまで、その変数は存在しますか?

はい。

「コンテナ」をベクトルへのポインタとして作成する必要がありますか?

いいえ、できますが、そうする必要はありません。

一般的に言えば、コンストラクターで new と結合されたポインターであるクラス インスタンス メンバーと、デストラクターで delete を使用しないことをお勧めします。非効率で面倒です。(既定のコピー コンストラクターはポインター値をコピーできます。その後、デストラクターは同じポインター値を 2 回削除できます。)


必要に応じて、次のことを検討してください。

int main(int argc, char* argv[])
{
  Foo foo;
  // other method calls to which foo is passed
  return 0;
}

fooはreturn 0;の後に範囲外になります。、自動的に削除されます。さらに、fooはヒープではなくスタックから割り当てられます。


The Annotated C++ Reference Manual の中古コピーが役立つ場合があります。古いものですが、信号対雑音比が高いです。

于 2009-01-01T04:59:56.197 に答える