私の知る限り、デストラクタでnew
で作成したものをすべて破棄し、開いているファイルストリームやその他のストリームを閉じます。ただし、C++の他のオブジェクトについては疑問があります。
std::vector
およびstd::string
s:それらは自動的に破壊されますか?
私のようなものがあれば
std::vector<myClass*>
クラスへのポインタの。ベクトルデストラクタが呼び出されるとどうなりますか?myClass
のデストラクタを自動的に呼び出しますか?または、ベクトルのみが破壊されますが、それに含まれるすべてのオブジェクトはまだメモリ内に存在しますか?
クラス内に別のクラスへのポインタがある場合、どうなりますか?
class A {
ClassB* B;
}
クラスAはコードのある時点で破棄されます。クラスBも破棄されるのでしょうか、それともポインターとクラスBがメモリ内のどこかにまだ存在するのでしょうか?
std :: vectorおよびstd :: strings:それらは自動的に破棄されますか?
はい(メンバー変数はstd::vector
およびstd::string
へのポインターではないと仮定します)。
Std :: vectorのようなものがある場合、ベクトルデストラクタが呼び出されるとどうなりますか? myClassのデストラクタを自動的に呼び出しますか?または、ベクトルのみが破壊されますが、それに含まれるすべてのオブジェクトはまだメモリ内に存在しますか?
vector<MyClass>
の場合、ベクターに含まれるすべてのオブジェクトが破棄されます。 vector<MyClass*>
の場合、すべてのオブジェクトは明示的にdelete
dである必要があります(破棄されるクラスがvector
内のオブジェクトを所有していると仮定)。 3番目の選択肢は、vector<shared_ptr<MyClass>>
のようなスマートポインターのvector
です。この場合、vector
の要素は明示的にdelete
dである必要はありません。
クラス内に別のクラスへのポインターがある場合はどうなりますか
B
は、明示的にdelete
dでなければなりません。繰り返しますが、スマートポインターを使用してB
の破棄を処理できます。
動的に作成したメモリについてのみ心配する必要があります(new
でメモリを予約するとき)。
例えば:
Class Myclass{
private:
char* ptr;
public:
~Myclass() {delete[] ptr;};
}
場合によります。 std::vector
およびstd::string
とMyClass
はすべて1つの共通点を持っています。変数をこれらの型のいずれかとして宣言すると、スタックに割り当てられ、現在のブロックに対してローカルになり、破壊されます。そのブロックが終了するとき。
例えば。
{
std::vector<std::string> a;
std::string b;
MyClass c;
} //at this point, first c will be destroyed, then b, then all strings in a, then a.
ポインターを取得する場合、正しく推測しました:ポインター自体が占有するメモリ(通常は4バイト整数)のみがスコープを離れると自動的に解放されます。明示的にdelete
しない限り(ベクトル内にあるかどうかに関係なく)、指すメモリには何も起こりません。他のオブジェクトへのポインタを含むクラスがある場合、mayはデストラクタでそれらを削除する必要があります(そのクラスかどうかによって異なります)/ownsそれらのオブジェクト)。 C++ 11には、ポインターを「通常の」オブジェクトと同様の方法で処理できるポインタークラス(スマートポインターと呼ばれる)があることに注意してください。
例:
{
std::unique_ptr<std::string> a = make_unique<std::string>("Hello World");
function_that_wants_string_ptr(a.get());
} //here a will call delete on it's internal string ptr and then be destroyed
自動ストレージにある場合は、はい。あなたが持つことができます std::string* s = new std::string
。この場合、自分で削除する必要があります。
何も、あなたが所有するメモリを手動で削除する必要があります(new
で割り当てられたメモリの場合)。
b
でnew
を割り当てた場合、デストラクタで明示的に破棄する必要があります。
経験則として、delete/delete[]
各new/new[]
コードに含まれています。
より良い経験則は、RAIIを使用し、生のポインターの代わりにスマートポインターを使用することです。
std::vector
、std::string
および私が知る限り、他のすべてのSTLコンテナには自動デストラクタがあります。これは、メモリリークを防ぐため、new
およびdelete
の代わりにこれらのコンテナを使用した方がよい場合が多い理由です。
myClass
オブジェクトへのポインターのベクトル(std::vector< myClass >
ではなく、ベクトルがmyClass
オブジェクトのベクトル(std::vector< myClass* >
)である場合にのみ、myClass
デストラクタが呼び出されます。 )。
最初の場合、std::vector
のデストラクタは、その各要素に対してmyClass
のデストラクタも呼び出します。 2番目の場合、std::vector
のデストラクタはmyClass*
のデストラクタを呼び出します。つまり、各ポインタを格納するために必要なスペースは解放されますが、myClass
を格納するために必要なスペースは解放されませんオブジェクト自体。
指し示すClass B
オブジェクトは破棄されませんが、そのポインターを格納するために割り当てられたスペースは解放されます。
はい。 std::vector
とstd::string
は、スコープから出ると自動的に含まれ、含まれるオブジェクトのデストラクタも呼び出します(std::vector
の場合)。
前に述べたように、std::vector
はスコープから外れると破棄され、含まれるオブジェクトのデストラクタを呼び出します。しかし実際、この場合、含まれるオブジェクトはポインターであり、ポインターが指すオブジェクトではありません。したがって、手動でdelete
する必要があります。
(2)と同じ。 Aは破棄されるため、ポインターは破壊されますが、クラスBは指しません。 delete
BというAのデストラクタを提供する必要があります。
C++ 11には非常に便利なソリューションがあります:std::unique_pointer
を使用します。単一のオブジェクトを指す場合にのみ使用できます。これは、ポインターが範囲外になると削除されます(たとえば、std::vector
を破棄する場合)。
Std :: vectorのようなものがある場合、ベクトルデストラクタが呼び出されるとどうなりますか?
場合によります。
valuesstd::vector <MyClass>
のベクトルがある場合、ベクトルのデストラクタは、ベクトル内のMyClass
のすべてのインスタンスに対してデストラクタを呼び出します。
pointersstd::vector <MyClass*>
のベクトルがある場合、MyClass
のインスタンスを削除する必要があります。
クラス内に別のクラスへのポインターがある場合はどうなりますか
ClassB
インスタンスはメモリに残ります。 ClassA
デストラクタを使用してジョブを作成する可能な方法は、B
をインスタンスメンバまたはスマートポインタにすることです。