質問
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;
}
上記のコードでは、変数<!> quot; container <!> quot;プライベートメンバー変数です。 <!> quot; Foo <!> quot;を呼び出しています。インスタンスを作成し、他のいくつかのメソッドとクラスに渡します。以下は私の疑問です
- 変数<!> quot; container <!> quot;のスコープは何ですか?インスタンスfooを削除するまで、その変数は存在しますか?
- <!> quot; container <!> quot;を作成する必要がありますか?ベクトルへのポインタとして?
助けてくれてありがとう
解決
- はい、コンテナメンバーの lifetime は、それを含むオブジェクトが存在する限り続きます。これは、それを指すポインター(
delete
場合)。 - いいえ、そうする理由はありません。ポインタにするには、
foo
の動的オブジェクトを作成する必要があります。この動的オブジェクトのライフタイムを管理する必要があります(コンテナポインタでdeleteを呼び出すことを含む)。ここでは不要です。 Fooオブジェクトと同じ長さのコンテナが必要であると仮定すると、ポインタを使用せずにコンテナを直接格納することに問題はありません。
vector<int>
ポインターを渡すと、ポインターが渡されます。それが指すオブジェクトはコピーされず、必要に応じてそれを指すポインターのみがコピーされます。 Javaを知っているなら、ポインタを渡すことはJavaのオブジェクトへの参照を渡すことと同じであると言ったら役立ちます。たとえば:
Foo f = new Foo();
// just passes the reference (pointer in C++) to doIt.
// the actual object is not copied
doIt(f);
他のヒント
<!> quot; Foo <!> quot;を呼び出しています。インスタンス
実際には、 class Foo のインスタンスを作成しています。
具体的には、 new()を介してヒープからメモリブロックを割り当てています。このメモリブロックは、 Foo :: container およびその他の Foo が必要とするオーバーヘッドクラスを含めるのに十分な大きさです。
(この例では何もありません。他のクラスでは、追加の属性または仮想ポインターテーブルが存在する可能性があります。)
当然、 new()は(おそらくデフォルト?) Foo :: Foo()コンストラクターを呼び出し、これが Foo :: container std :: vector コンストラクター。
変数<!> quot; container <!> quot;?
のスコープはどのようになりますかcontainer は、インスタンス foo の属性[コンポーネント]です。インスタンス foo が存在する限り存在します。
スコープごとに、 Foo :: container について話すことができます。ただし、クラス Foo のインスタンスなしでは Foo :: constainer にアクセスできません。 (例:オブジェクト foo 。) Foo :: constainer は、クラス Foo のインスタンスなしでは存在しません。
(1つの値がすべてのインスタンスで共有される、多少異なる動作をするクラス変数があります。しかし、ここではそうではありません。)
このスコープは、公開/保護/プライベート/友人のメンバーアクセス制御に対して無関係です。
たとえば、一部の Foo :: myPublicMethod()では、 Foo :: container を参照できます。この状況では明示的なスコープを無視して、単にコンテナと呼ぶこともできます。
プライベートであるため、クラス Fooのメソッドの外部では Foo :: container にアクセスできません。
インスタンスfooを削除するまでその変数は存在しますか?
はい。
<!> quot; container <!> quot;を作成する必要がありますか?ベクトルへのポインタとして?
いいえ。可能ですが、そうする必要はありません。
一般的に、クラスインスタンスメンバーは、コンストラクターの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 が割り当てられます。
注釈付きC ++リファレンスマニュアルの使用済みコピーが役立つ場合があります。 。古いですが、信号対雑音比が高いです。