ΠΠ°ΠΊ C++ ΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ ΠΏΠ°ΠΌΡΡΡΡ?
ΠΠΎΠ³Π΄Π° ΠΌΡ Π³ΠΎΠ²ΠΎΡΠΈΠΌ ΠΏΡΠΎ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ°ΠΌΡΡΡΡ Π² C++, ΠΌΡ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½ΠΎ ΠΎΠ±ΡΠ°ΡΠ°Π΅ΠΌΡΡ ΠΊ ΡΠ΅ΡΠΌΠΈΠ½Ρ storage duration (Π΄Π»ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ). Storage duration β ΡΡΠΎ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΎΠΏΠΈΡΡΠ²Π°Π΅Ρ, ΠΊΠΎΠ³Π΄Π° ΡΠΎΡ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ Π² ΠΏΠ°ΠΌΡΡΡ ΠΈ ΠΊΠΎΠ³Π΄Π° Π΅Ρ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ.
Π C++ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΡΠ΅ΡΡΡΠ΅ Π²ΠΈΠ΄Π° [1] storage duration:
- ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠ°Ρ storage duration. ΠΠΎΠ³Π΄Π° ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π²Ρ ΠΎΠ΄ΠΈΡ Π² ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠ° (ΡΠ°ΠΊΠΆΠ΅ ΠΈΠ·Π²Π΅ΡΡΠ½ΡΡ ΠΊΠ°ΠΊ scope [2]), ΠΎΠ½ ΡΠ°Π·ΠΌΠ΅ΡΠ°Π΅ΡΡΡ Π² Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΏΠ°ΠΌΡΡΠΈ, Π·Π°ΡΠ°ΡΡΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΉ Π² Π²ΠΈΠ΄Π΅ ΡΡΠ΅ΠΊΠ°; ΠΊΠΎΠ³Π΄Π° ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΠΊΠΈΠ΄Π°Π΅Ρ ΡΡΡ ΠΎΠ±Π»Π°ΡΡΡ, Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ Π΄Π΅ΡΡΡΡΠΊΡΠΎΡ ΠΈ ΠΏΠ°ΠΌΡΡΡ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅ΡΡΡ.
//ΠΠΎΠ΄ΠΎΠΏΡΡΠ½ΡΠΉ ΠΊΠ»Π°ΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π½Π° ΠΏΡΠΎΡΡΠΆΠ΅Π½ΠΈΠΈ Π²ΡΠ΅ΠΉ ΡΡΠ°ΡΡΠΈ
class X {
int a;
double b;
public:
void func() {};
};
int main() {
X object; //Π ΠΏΠ°ΠΌΡΡΠΈ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΊΠ»Π°ΡΡΠ° X
{
X object2; //ΠΡΡ ΠΎΠ΄ΠΈΠ½ ΠΎΠ±ΡΠ΅ΠΊΡ ΡΠ°Π·ΠΌΠ΅ΡΡΠ½ Π² ΠΏΠ°ΠΌΡΡΠΈ
//Π Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π² ΠΏΠ°ΠΌΡΡΠΈ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½Ρ ΠΈ Π΄ΠΎΡΡΡΠΏΠ½Ρ ΠΎΠ±Π° ΠΎΠ±ΡΠ΅ΠΊΡΠ°
} //ΠΠ΄Π΅ΡΡ object2 Π²ΡΡ
ΠΎΠ΄ΠΈΡ ΠΈΠ· ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΈ ΡΠ½ΠΈΡΡΠΎΠΆΠ°Π΅ΡΡΡ
} //ΠΠ΄Π΅ΡΡ ΡΠ½ΠΈΡΡΠΎΠΆΠ°Π΅ΡΡΡ object
- Π‘ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠ°Ρ ΡΠ²ΡΠ·Π°Π½Π° Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠ²
static
ΠΈextern
. ΠΠ±ΡΠ΅ΠΊΡΡ ΡΠΎ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠΉ storage duration ΡΠΎΠ·Π΄Π°ΡΡΡΡ ΠΏΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΈ ΡΠ΄Π°Π»ΡΡΡΡΡ ΠΏΡΠΈ Π΅Ρ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠΈ. - Storage duration ΠΏΠΎΡΠΎΠΊΠ° ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ
thread_local
. ΠΠΌΠ΅ΡΡΠΈΠ΅ ΡΡΡ storage duration ΠΎΠ±ΡΠ΅ΠΊΡΡ ΡΠΎΠ·Π΄Π°ΡΡΡΡ ΠΏΡΠΈ ΡΡΠ°ΡΡΠ΅ ΠΏΠΎΡΠΎΠΊΠ° ΠΈ ΡΠ΄Π°Π»ΡΡΡΡΡ ΠΏΡΠΈ Π΅Π³ΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠΈ. - ΠΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠ°Ρ storage duration Π½Π΅ΡΠ°Π·ΡΡΠ²Π½ΠΎ ΡΠ²ΡΠ·Π°Π½Π° Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΊΠ»ΡΡΠ΅Π²ΡΡ
ΡΠ»ΠΎΠ²
new
ΠΈdelete
.
X* ptr = nullptr; //Π£ΠΊΠ°Π·Π°ΡΠ΅Π»Ρ, Π½Π΅ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡΠΈΠΉ Π½ΠΈ Π½Π° ΡΡΠΎ
{
X* ptr2 = new X(); //Π Π°Π·ΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΠΊΠ»Π°ΡΡΠ° X Π² ΠΏΠ°ΠΌΡΡΠΈ (ΡΠ°ΠΊΠΆΠ΅ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎΠΉ ΠΊΠ°ΠΊ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠ°Ρ ΠΏΠ°ΠΌΡΡΡ, Π·Π°ΡΠ°ΡΡΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΉ Π² Π²ΠΈΠ΄Π΅ ΠΊΡΡΠΈ). ptr2 - ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΡΡΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡ
ptr = ptr2; //ptr ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π½Π° ΡΠΎΡ ΠΆΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡ
} //Π£ΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ptr2 Π²ΡΡ
ΠΎΠ΄ΠΈΡ ΠΈΠ· ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΈ ΡΠ½ΠΈΡΡΠΎΠΆΠ°Π΅ΡΡΡ, Π½ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ, Π½Π° ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠ½ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ, ΠΎΡΡΠ°ΡΡΡΡ Π² ΠΏΠ°ΠΌΡΡΠΈ
delete ptr; //ΠΡΠΎΠΈΡΡ
ΠΎΠ΄ΠΈΡ Π²ΡΠ·ΠΎΠ² Π΄Π΅ΡΡΡΡΠΊΡΠΎΡΠ°, Π° ΠΏΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ, Π½Π° ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ptr, ΡΠ΄Π°Π»ΡΠ΅ΡΡΡ ΠΈΠ· ΠΏΠ°ΠΌΡΡΠΈ
ΠΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ, ΡΡΠΎ Π² ΡΠ»ΡΡΠ°Π΅ Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠΉ storage duration ΠΏΠ°ΠΌΡΡΡ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅ΡΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ, Π° Π² ΡΠ»ΡΡΠ°Π΅ Ρ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠΉ β Π²ΡΡΡΠ½ΡΡ. ΠΠΎΡΠ΅ΠΌΡ ΠΆΠ΅ ΡΠΎΠ³Π΄Π° Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π²ΡΠ΅Π³Π΄Π° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΡΡ ΠΏΠ°ΠΌΡΡΡ?
- Π§ΡΠΎΠ±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠ΅ΠΊ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°ΡΠ°Π½Π΅Π΅ Π½Π° ΡΡΠ°ΠΏΠ΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ Π·Π½Π°ΡΡ, ΠΊΠ°ΠΊ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠ°ΠΌΡΡΠΈ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ, Π° ΡΡΠΎ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ Π½Π΅ Π²ΡΠ΅Π³Π΄Π°.
- ΠΠ½ΠΎΠ³Π΄Π° Π½Π°Π΄ΠΎ, ΡΡΠΎΠ±Ρ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΎΡΡΠ°Π²Π°Π»ΡΡ Π² ΠΏΠ°ΠΌΡΡΠΈ ΠΈ ΠΏΠΎΡΠ»Π΅ Π²ΡΡ ΠΎΠ΄Π° ΠΈΠ· ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ Π² ΠΊΠΎΡΠΎΡΠΎΠΉ Π±ΡΠ» ΡΠΎΠ·Π΄Π°Π½, Π° Π² ΡΠ»ΡΡΠ°Π΅ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π½Π° ΡΡΠ΅ΠΊΠ΅ ΡΡΠΎ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.
Π§ΡΠΎΠ±Ρ ΠΎΠ±ΠΎΠΉΡΠΈ ΡΡΠΈ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΡΡ ΠΏΠ°ΠΌΡΡΡ ΠΏΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΌΡ ΠΈ Π±ΡΠ΄Π΅ΠΌ ΡΠ΅Π³ΠΎΠ΄Π½Ρ Π³ΠΎΠ²ΠΎΡΠΈΡΡ.
Π§ΡΠΎ ΡΠ°ΠΊΠΎΠ΅ ΡΠΌΠ½ΡΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ ΠΈ Π·Π°ΡΠ΅ΠΌ ΠΎΠ½ΠΈ Π½ΡΠΆΠ½Ρ?
ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΡΡ ΠΏΠ°ΠΌΡΡΡ, ΠΎΡΠ»ΠΈΡΠ½ΠΎ. Π’Π΅ΠΏΠ΅ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΌΠΎΠ³ΡΡ ΠΏΠΎΠΊΠΈΠ΄Π°ΡΡ ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ, Π³Π΄Π΅ Π±ΡΠ»ΠΈ ΡΠΎΠ·Π΄Π°Π½Ρ, ΠΈ ΠΈΠΌΠ΅ΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌΡΠΉ Π²ΠΎ Π²ΡΠ΅ΠΌΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΡΠ°Π·ΠΌΠ΅Ρ β ΠΆΠΈΠ·Π½Ρ ΡΡΠ°Π»Π° Π½Π°Π»Π°ΠΆΠΈΠ²Π°ΡΡΡΡ ΠΈ ΠΆΠ°Π»ΠΎΠ²Π°ΡΡΡΡ ΠΊΠ°ΠΊ Π±ΡΠ΄ΡΠΎ Π½Π΅ Π½Π° ΡΡΠΎ.
ΠΡΠ΅Π΄Π»Π°Π³Π°Π΅ΠΌ Π²Π·Π³Π»ΡΠ½ΡΡΡ Π½Π° ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΡΠ°Π³ΠΌΠ΅Π½Ρ ΠΊΠΎΠ΄Π°:
#include <memory>
). ΠΠ»Ρ ΠΊΡΠ°ΡΠΊΠΎΡΡΠΈ Π²ΠΎ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠ°Ρ
ΠΊΠΎΠ΄Π° Π²Π½ΡΡΡΠΈ ΡΡΠ°ΡΡΠΈ ΡΡΠΎ Π±ΡΠ»ΠΎ ΠΎΠΏΡΡΠ΅Π½ΠΎ. X* ptr = new X();
if (func()) {
func2();
return;
}
delete ptr;
ΠΠ° ΠΏΠ΅ΡΠ²ΡΠΉ Π²Π·Π³Π»ΡΠ΄, Π·Π΄Π΅ΡΡ Π²ΡΡ Ρ ΠΎΡΠΎΡΠΎ, Π½ΠΎ Π΅ΡΡΡ Π½ΡΠ°Π½ΡΡ:
- ΠΡΠ»ΠΈ
func()
Π²ΡΠ±ΡΠΎΡΠΈΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅, ΡΠΎ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π΅ Π΄ΠΎΠΉΠ΄ΡΡ Π΄ΠΎdelete
ΠΈ ΠΏΠ°ΠΌΡΡΡ Π½Π΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡΡΡ. - ΠΡΠ»ΠΈ
func()
Π²Π΅ΡΠ½ΡΡ true, ΡΠΎ ΠΏΠΎΡΠ»Π΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡfunc2()
ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΠΊΠΈΠ½Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ, Π½ΠΎ ΠΏΠ°ΠΌΡΡΡ Π½Π΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡΡΡ, Ρ.ΠΊ. Π°Π²ΡΠΎΡ ΠΊΠΎΠ΄Π° Π·Π°Π±ΡΠ» Π΄ΠΎΠ±Π°Π²ΠΈΡΡdelete
Π²Π½ΡΡΡΡ ΡΡΠ»ΠΎΠ²ΠΈΡ. - ΠΡΠ»ΠΈ Π±Ρ Π°Π²ΡΠΎΡ Π·Π°Π±ΡΠ»
delete
ΡΠ°ΠΊΠΆΠ΅ Π² 6-ΠΉ ΡΡΡΠΎΠΊΠ΅, ΠΏΠ°ΠΌΡΡΡ ΡΠΎΠΆΠ΅ Π½Π΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΠ»Π°ΡΡ Π±Ρ.
new/delete
. ΠΠ°ΠΊ β ΡΠ²ΠΈΠ΄ΠΈΠΌ Π½ΠΈΠΆΠ΅.ΠΠΎΠΌΠΈΠΌΠΎ ΠΏΡΠΎΠ±Π»Π΅ΠΌ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ Ρ new/delete
, ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° ΠΈ Ρ ΠΏΡΠΎΡΡΡΠΌΠΈ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΡΠΌΠΈ. ΠΠ½Π° Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΠΈ ΡΠ°Π·Π΄Π΅Π»Π΅Π½ΠΈΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ Π²Π»Π°Π΄Π΅ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ (owning pointer), Π° Π·Π½Π°ΡΠΈΡ, ΠΈ ΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½Ρ Π·Π° Π²ΡΠ·ΠΎΠ² new/delete
, ΠΈ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ (non owning pointer).
ΠΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡΠΎΡΡΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ (ΡΠ°ΠΊΠΆΠ΅ ΠΈΠ·Π²Π΅ΡΡΠ½ΡΡ ΠΊΠ°ΠΊ raw pointers) Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π±Π΅Π· Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠ΅Π² ΠΈΠ»ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΈΠ·ΡΡΠ΅Π½ΠΈΡ ΠΊΠΎΠ΄Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ, ΠΊΠ°ΠΊΠΎΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ Π²Π»Π°Π΄Π΅Π΅Ρ, Π° ΠΊΠ°ΠΊΠΎΠΉ β ΡΠΎΠ»ΡΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ. ΠΠ·Π³Π»ΡΠ½ΠΈΡΠ΅ Π½Π° ΡΠ»Π΅Π΄ΡΡΡΡΡ Π΄Π΅ΠΊΠ»Π°ΡΠ°ΡΠΈΡ:
int* func();
ΠΠ»Π°Π²Π½Π°Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Π·Π΄Π΅ΡΡ, ΡΡΠΎ ΡΠΎΠΌΡ, ΠΊΡΠΎ Π±ΡΠ΄Π΅Ρ Π²ΡΠ·ΡΠ²Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ, ΡΠΎΠ²Π΅ΡΡΠ΅Π½Π½ΠΎ Π½Π΅ΡΡΠ½ΠΎ, Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΠ½ Π²ΡΠ·Π²Π°ΡΡ delete
Π΄Π»Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠ³ΠΎ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΠΈΠ»ΠΈ Π·Π° ΡΡΠΎ ΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π΅Π½ ΠΊΠΎΠ΄ Π³Π΄Π΅-ΡΠΎ Π² Π΄ΡΡΠ³ΠΎΠΉ ΡΠ°ΡΡΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. ΠΠ½Π°ΡΠ΅ Π³ΠΎΠ²ΠΎΡΡ, Π·Π΄Π΅ΡΡ Π½Π΅ Π²ΠΈΠ΄Π½ΠΎ, ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π²Π»Π°Π΄Π΅ΡΡΠΈΠΌ ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠΈΠΌ.
ΠΡΠ΅ Π²ΡΡΠ΅Π½Π°Π·Π²Π°Π½Π½ΡΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΠΈΠ·ΡΡΠ½ΠΎ ΡΠ΅ΡΠ°ΡΡΡΡ ΡΠΌΠ½ΡΠΌΠΈ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΡΠΌΠΈ. Π£ΠΌΠ½ΡΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ Π² C++ β ΡΡΠΎ Π½Π΅ ΡΡΠΎ-ΡΠΎ ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΎΠ΅, Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠ΅ Π² ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ ΡΠ·ΡΠΊΠ°, Π° Π½Π΅ Π±ΠΎΠ»Π΅Π΅ ΡΠ΅ΠΌ Π½Π°Π±ΠΎΡ ΠΊΠ»Π°ΡΡΠΎΠ² ΠΈΠ· ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ. Π Π°Π·Π±Π΅ΡΡΠΌΡΡ Ρ Π½ΠΈΠΌΠΈ ΠΎΠ΄ΠΈΠ½ Π·Π° ΠΎΠ΄Π½ΠΈΠΌ.
std::unique_ptr
ΠΠ΅ΡΠ²ΡΠΌ ΡΠΌΠ½ΡΠΌ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΌ, Ρ ΠΊΠΎΡΠΎΡΡΠΌ ΠΌΡ ΠΏΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΠΌΡΡ, Π±ΡΠ΄Π΅Ρ std::unique_ptr
[3]. ΠΠ½ ΡΡΡΠ»Π°Π΅ΡΡΡ Π½Π° ΠΎΠ±ΡΠ΅ΠΊΡ Π² Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΏΠ°ΠΌΡΡΠΈ ΠΈ ΠΏΡΠΈ Π²ΡΡ
ΠΎΠ΄Π΅ ΠΈΠ· ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΡΠ½ΠΈΡΡΠΎΠΆΠ°Π΅Ρ Ρ
ΡΠ°Π½ΠΈΠΌΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ. ΠΠ·Π³Π»ΡΠ½Π΅ΠΌ Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ ΠΊΠΎΠ΄Π° Π½ΠΈΠΆΠ΅:
{
std::unique_ptr<X> ptr(new X()); //ΠΠ±ΡΠ΅ΠΊΡ ΠΊΠ»Π°ΡΡΠ° X ΡΠΎΠ·Π΄Π°Π½ Π² Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΏΠ°ΠΌΡΡΠΈ
} //ΠΠ΄Π΅ΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ptr ΠΏΠΎΠΊΠΈΠ΄Π°Π΅Ρ ΡΠ²ΠΎΡ ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΈ ΡΠ½ΠΈΡΡΠΎΠΆΠ°Π΅ΡΡΡ, Π½ΠΎ ΠΏΠ΅ΡΠ΅Π΄ ΡΡΠΈΠΌ ΡΠ΄Π°Π»ΡΠ΅Ρ ΠΈΠ· ΠΏΠ°ΠΌΡΡΠΈ ΠΎΠ±ΡΠ΅ΠΊΡ, Π½Π° ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ
ΠΠΎΠ³Π΄Π° std::unique_ptr
Π²ΡΡ
ΠΎΠ΄ΠΈΡ ΠΈΠ· ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ, ΡΡΠ΅ΡΠΊΠΈ ΠΏΠ°ΠΌΡΡΠΈ Π½Π΅ ΠΏΡΠΎΠΈΡΡ
ΠΎΠ΄ΠΈΡ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π² ΡΠ²ΠΎΠ΅ΠΌ Π΄Π΅ΡΡΡΡΠΊΡΠΎΡΠ΅ ΡΠΌΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π²ΡΠ·ΡΠ²Π°Π΅Ρ delete
Π΄Π»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π½Π° ΠΊΠΎΡΠΎΡΡΠΉ ΡΡΡΠ»Π°Π΅ΡΡΡ, Π²ΡΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Ρ ΡΠ΅ΠΌ ΡΠ°ΠΌΡΠΌ ΠΏΠ°ΠΌΡΡΡ.
new/delete
, ΠΎΠ½ΠΈ Π»ΠΈΡΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΡ Π½Π΅ Π΄Π΅Π»Π°ΡΡ ΡΡΠΎΠ³ΠΎ ΠΈ, ΠΊΠ°ΠΊ ΡΠ»Π΅Π΄ΡΡΠ²ΠΈΠ΅, Π·Π°ΡΠΈΡΠ°ΡΡ Π΅Π³ΠΎ ΠΎΡ ΠΎΡΠΈΠ±ΠΎΠΊ.ΠΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ Ρ Π²Π½Π΅Π·Π°ΠΏΠ½ΡΠΌΠΈ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡΠΌΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠΈΡ
ΡΠΌΠ½ΡΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ (Π² ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ std::unique_ptr
) ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΠΎΠ² Π·Π°ΡΠΈΡΠ°Π΅Ρ ΡΠ°Π·Π²ΡΡΡΡΠ²Π°Π½ΠΈΠ΅ ΡΡΠ΅ΠΊΠ° (stack-unwinding [4]).
ΠΠΎΠ΄ΡΠΎΠ±Π½ΠΎΠ΅ ΡΠ°ΡΡΠΌΠΎΡΡΠ΅Π½ΠΈΠ΅ ΡΡΠΎΠ³ΠΎ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠ° Π‘++ Π²ΡΡ ΠΎΠ΄ΠΈΡ Π·Π° ΡΠ°ΠΌΠΊΠΈ ΡΡΠ°ΡΡΠΈ, Π½ΠΎ Π³Π»Π°Π²Π½ΠΎΠ΅, ΡΡΠΎ Π½ΡΠΆΠ½ΠΎ Π·Π½Π°ΡΡ ΠΎ Π½ΡΠΌ β Π΅ΡΠ»ΠΈ Π½Π° ΡΡΠ΅ΠΊΠ΅ Π±ΡΠ» ΡΠΎΠ·Π΄Π°Π½ ΠΎΠ±ΡΠ΅ΠΊΡ, Π° ΠΏΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ Π±ΡΠ»ΠΎ Π²ΡΠ±ΡΠΎΡΠ΅Π½ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅, C++ Π³Π°ΡΠ°Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎ Π²ΡΠ·ΠΎΠ²Π΅Ρ Π΄Π΅ΡΡΡΡΠΊΡΠΎΡ Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°. ΠΡΠΎ Π·Π½Π°ΡΠΈΡ, ΡΡΠΎ Π΅ΡΠ»ΠΈ ΠΌΡ ΠΎΠ±Π½ΠΎΠ²ΠΈΠΌ ΠΊΠΎΠ΄ Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 3 ΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ ΠΎΠ½ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π» ΡΠΌΠ½ΡΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ, ΡΠΎ ΠΈΠ·Π±Π°Π²ΠΈΠΌΡΡ ΠΎΡ Π²ΡΠ΅Ρ ΡΡΡΡ Π²ΡΡΠ΅Π½Π°Π·Π²Π°Π½Π½ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ:
std::unique_ptr<X> ptr(new X());
if (func()) {
func2();
return;
}
Π’Π΅ΠΏΠ΅ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΡ Π½Π΅ Π½Π°Π΄ΠΎ ΡΡΠ°Π²ΠΈΡΡ delete
, Π° Π² ΡΠ»ΡΡΠ°Π΅, Π΅ΡΠ»ΠΈ ΠΎΠ΄Π½Π° ΠΈΠ· ΡΡΠ½ΠΊΡΠΈΠΉ Π²ΡΠ±ΡΠΎΡΠΈΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅, ΡΠ°Π·Π²ΡΡΡΡΠ²Π°Π½ΠΈΠ΅ ΡΡΠ΅ΠΊΠ° Π·Π°ΡΠΈΡΠΈΡ Π½Π°Ρ ΠΎΡ ΡΡΠ΅ΡΠΊΠΈ ΠΏΠ°ΠΌΡΡΠΈ.
Π Π²ΡΡ Π±Ρ Ρ
ΠΎΡΠΎΡΠΎ, Π½ΠΎ ΠΌΡ ΠΏΠΎ-ΠΏΡΠ΅ΠΆΠ½Π΅ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ new
. Π§ΡΠΎΠ±Ρ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ new/delete
ΡΠΎΠ±Π»ΡΠ΄Π°Π»ΠΎΡΡ, Π±ΡΠ»Π° ΠΏΡΠΈΠ΄ΡΠΌΠ°Π½Π° ΡΡΠ½ΠΊΡΠΈΡ std::make_unique
[5], ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ std::unique_ptr
, Π½ΠΎ Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΌΠΈ ΡΠΈΡΠ°ΠΌΠΈ:
- Π’Π΅ΠΏΠ΅ΡΡ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
new/delete
ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΡΠΎΠ±Π»ΡΠ΄Π΅Π½ΠΎ. std::make_unique
ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π΅ ΠΏΠΈΡΠ°ΡΡ ΠΈΠΌΡ ΠΊΠ»Π°ΡΡΠ° Π΄Π²Π°ΠΆΠ΄Ρ:
auto ptr = std::make_unique<X>();
std::make_unique
ΡΠ΅ΡΠ°Π΅Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π½Π΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΡΠ΄ΠΊΠ° Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ² (unspecified evaluation order). Π Π°ΡΡΠΌΠΎΡΡΠΈΠΌ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΡΠ°Π³ΠΌΠ΅Π½Ρ ΠΊΠΎΠ΄Π°:
void func(std::unique_ptr<A> a, std::unique_ptr<B> b) {}
int main() {
func(std::unique_ptr<A>(new A()), std::unique_ptr<B>(new B()));
}
ΠΠ΄Π΅ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΏΠΎΡΡΠ΄ΠΎΠΊ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ²:
new A()
new B()
std::unique_ptr<A>(...)
std::unique_ptr<B>(...)
ΠΡΠ»ΠΈ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ new B()
ΠΏΡΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅, Π·Π°Π½ΡΡΠ°Ρ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ new A()
ΠΏΠ°ΠΌΡΡΡ Π½Π΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡΡΡ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΡΠΌΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π΅ΡΡ Π½Π΅ Π±ΡΠ» ΡΠΎΠ·Π΄Π°Π½, Π° delete
Π½ΠΈΠΊΡΠΎ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΈ Π½Π΅ ΡΠΎΠ±ΠΈΡΠ°Π»ΡΡ. ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ std::make_unique
ΡΠ΅ΡΠ°Π΅Ρ ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ.
std::unique_ptr
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±ΡΠ΅ΠΊΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅ΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π²Π»Π°Π΄Π΅Π»ΡΡΠ°, ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΏΡΠ°Π²ΠΎ Π½Π° Π²Π»Π°Π΄Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΡ-ΡΠΎ Π΄ΡΡΠ³ΠΎΠΌΡ. Π§ΡΠΎΠ±Ρ ΡΡΠΎ ΡΠ΄Π΅Π»Π°ΡΡ, Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ std::move
[6]. Π Π°ΡΡΠΌΠΎΡΡΠΈΠΌ ΠΊΠΎΠ΄:
void func(std::unique_ptr<X> a) {}
int main() {
auto a = std::make_unique<X>();
func(a); //ΠΠ΅ ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΡΠ΅ΡΡΡ, std::unique_ptr Π½Π΅Π»ΡΠ·Ρ ΠΊΠΎΠΏΠΈΡΠΎΠ²Π°ΡΡ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΠΈΠ½Π°ΡΠ΅ Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π±ΡΠ»ΠΎ Π±Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π²Π»Π°Π΄Π΅Π»ΡΡΠ΅Π²
func(std::move(a)); //ΠΠ»Π°Π΄Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ ΠΏΠ΅ΡΠ΅Π΄Π°Π½ΠΎ Π² func, main Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ Π²Π»Π°Π΄Π΅Π΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ, Π½Π° Π²ΡΡ
ΠΎΠ΄Π΅ ΠΈΠ· func ΠΎΠ±ΡΠ΅ΠΊΡ Π±ΡΠ΄Π΅Ρ ΡΠ½ΠΈΡΡΠΎΠΆΠ΅Π½
}
Π Π°Π· std::unique_ptr
Π½Π΅Π»ΡΠ·Ρ ΠΊΠΎΠΏΠΈΡΠΎΠ²Π°ΡΡ, ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ Π½Π΅ΠΏΠΎΠ½ΡΡΠ½ΠΎ, ΠΊΠ°ΠΊ ΡΠ°Π·ΡΠ΅ΡΠΈΡΡ ΠΊΠΎΠΌΡ-ΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ, Π½Π΅ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Ρ Π΅ΠΌΡ ΠΏΡΠ°Π²ΠΎ Π½Π° Π²Π»Π°Π΄Π΅Π½ΠΈΠ΅. ΠΡΠ΅Π½Ρ ΠΏΡΠΎΡΡΠΎ: Π½ΡΠΆΠ½ΠΎ Π²ΡΠ΅Π³ΠΎ Π»ΠΈΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΡΠΎΠ·Π΄Π°Π½Π½ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° get()
, ΠΊΠ°ΠΊ Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 10. ΠΠ΄Π½Π°ΠΊΠΎ Π±ΡΠ΄ΡΡΠ΅ Π²Π½ΠΈΠΌΠ°ΡΠ΅Π»ΡΠ½Ρ: Π½Π΅ Π΄ΠΎΠΏΡΡΠΊΠ°ΠΉΡΠ΅ ΡΠΈΡΡΠ°ΡΠΈΠΈ, ΠΊΠΎΠ³Π΄Π° std::unique_ptr
Π²ΠΌΠ΅ΡΡΠ΅ Ρ Ρ
ΡΠ°Π½ΠΈΠΌΡΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ Π±ΡΠ»ΠΈ ΡΠ½ΠΈΡΡΠΎΠΆΠ΅Π½Ρ, Π½ΠΎ Π³Π΄Π΅-ΡΠΎ ΠΏΠΎ-ΠΏΡΠ΅ΠΆΠ½Π΅ΠΌΡ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡΠΈΠΉ Π½Π° Π½Π΅Π²Π°Π»ΠΈΠ΄Π½ΡΡ (ΡΠΆΠ΅) ΠΎΠ±Π»Π°ΡΡΡ ΠΏΠ°ΠΌΡΡΠΈ.
void func(X* a) {}
int main() {
auto a = std::make_unique<X>();
func(a.get());
}
ΠΠΎΠ³Π΄Π° Π² ΠΊΠΎΠ΄Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ ΠΏΡΠΎΡΡΡΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ ΠΈ ΡΠΌΠ½ΡΠ΅, ΡΡΠ°Π·Ρ ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ ΠΏΠΎΠ½ΡΡΠ½ΠΎ, Π³Π΄Π΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π²Π»Π°Π΄Π΅Π΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ, Π° Π³Π΄Π΅ β ΡΠΎΠ»ΡΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ.
get()
ΠΏΡΠΎΡΡΡΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ ΠΎΡ Π»ΡΠ±ΡΡ
Π΄ΡΡΠ³ΠΈΡ
ΠΏΡΠΎΡΡΡΡ
ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ, Π±ΡΠ» ΠΏΡΠΈΠ΄ΡΠΌΠ°Π½std::experimental::observer_ptr
[7], Π½ΠΎ Π½Π° Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ ΠΎΠ½ Π΅ΡΡ Π½Π΅ Π²ΠΎΡΡΠ» Π² ΡΡΠ°Π½Π΄Π°ΡΡ.std::unique_ptr
β ΡΡΠΎ ΡΠΌΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ, ΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌ Π²Ρ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠ΄ΡΠΌΠ°ΡΡ Π² ΠΏΠ΅ΡΠ²ΡΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ, ΠΊΠΎΠ³Π΄Π° ΡΠ΅ΡΠΈΡΠ΅ ΡΠ°Π·ΠΌΠ΅ΡΡΠΈΡΡ ΡΡΠΎ-Π½ΠΈΠ±ΡΠ΄Ρ Π² Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΏΠ°ΠΌΡΡΠΈ. ΠΡΠΎ Π²Π°Ρ ΡΠΌΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.
std::shared_ptr ΠΈ std::weak_ptr
std::unique_ptr
ΠΈ ΠΏΡΠ°Π²Π΄Π° Ρ
ΠΎΡΠΎΡ, Π½ΠΎ ΠΎΠ½ Π½Π΅ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ Π² ΡΠΈΡΡΠ°ΡΠΈΠΈ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ Ρ
ΠΎΡΠΈΠΌ, ΡΡΠΎΠ±Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΡΠ°Π±ΠΎΡΠ°Π»ΠΈ Ρ ΠΎΠ΄Π½ΠΈΠΌ ΠΎΠ±ΡΠΈΠΌ ΡΠ΅ΡΡΡΡΠΎΠΌ ΠΈ ΡΡΠΎΠ±Ρ Π² ΠΌΠΎΠΌΠ΅Π½Ρ, ΠΊΠΎΠ³Π΄Π° Π²ΡΠ΅ ΡΡΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΡ Π±ΡΠ»ΠΈ Π²ΡΠ³ΡΡΠΆΠ΅Π½Ρ ΠΈΠ· ΠΏΠ°ΠΌΡΡΠΈ, Π·Π° Π½Π΅Π½Π°Π΄ΠΎΠ±Π½ΠΎΡΡΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ Π²ΡΠ³ΡΡΠ·ΠΈΠ»ΡΡ Π±Ρ ΠΈ ΡΠ΅ΡΡΡΡ.
Π ΡΠ°ΠΊΠΎΠΉ ΡΠΈΡΡΠ°ΡΠΈΠΈ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ std::shared_ptr
[8]. ΠΡΠΎΡ ΡΠΌΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΡΠ°Π·ΡΠ΅ΡΠ°Π΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΈΠΌΠ΅ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π²Π»Π°Π΄Π΅Π»ΡΡΠ΅Π², Π° ΠΊΠΎΠ³Π΄Π° Π²ΡΠ΅ Π²Π»Π°Π΄Π΅Π»ΡΡΡ ΡΠ½ΠΈΡΡΠΎΠΆΠ°ΡΡΡΡ, ΡΠ½ΠΈΡΡΠΎΠΆΠ°Π΅ΡΡΡ ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡ. Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π΄ΠΎΡΡΠΈΠ³Π°Π΅ΡΡΡ Π·Π° ΡΡΡΡ Π½Π°Π»ΠΈΡΠΈΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΡΡΡΡΠΈΠΊΠ° ΡΡΡΠ»ΠΎΠΊ Π²Π½ΡΡΡΠΈ std::shared_ptr
. ΠΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π·, ΠΊΠΎΠ³Π΄Π° ΡΠ°ΠΊΠΎΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΠΊΠΎΠΏΠΈΡΡΠ΅ΡΡΡ, ΡΡΡΡΡΠΈΠΊ ΠΈΠ½ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠΈΡΡΠ΅ΡΡΡ, Π° ΠΊΠΎΠ³Π΄Π° ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ ΡΠ½ΠΈΡΡΠΎΠΆΠ°Π΅ΡΡΡ β Π΄Π΅ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠΈΡΡΠ΅ΡΡΡ. Π ΠΌΠΎΠΌΠ΅Π½Ρ, ΠΊΠΎΠ³Π΄Π° ΡΡΡΡΡΠΈΠΊ Π΄ΠΎΡΡΠΈΠ³Π°Π΅Ρ Π½ΡΠ»Ρ, ΠΎΠ±ΡΠ΅ΠΊΡ ΡΠ½ΠΈΡΡΠΎΠΆΠ°Π΅ΡΡΡ. ΠΠΎΡΠΌΠΎΡΡΠΈΠΌ Π½Π° ΠΊΠΎΠ΄:
{
std::shared_ptr<X> ptr = std::make_shared<X>(); //Π‘ΠΎΠ·Π΄Π°ΡΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ
{
std::shared_ptr<X> ptr2 = ptr; //Π’Π΅ΠΏΠ΅ΡΡ Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π΄Π²Π° Π²Π»Π°Π΄Π΅Π»ΡΡΠ°, Π²ΡΡΠ°ΠΆΠ΅Π½Π½ΡΡ
Π² Π²ΠΈΠ΄Π΅ ptr ΠΈ ptr2
} //ptr2 Π²ΡΡ
ΠΎΠ΄ΠΈΡ ΠΈΠ· ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ, Π½ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ Π½Π΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅ΡΡΡ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π΅ΡΡΡ ptr, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎ-ΠΏΡΠ΅ΠΆΠ½Π΅ΠΌΡ ΡΡΡΠ»Π°Π΅ΡΡΡ Π½Π° Π½Π΅Π³ΠΎ
} //ptr Π²ΡΡ
ΠΎΠ΄ΠΈΡ ΠΈΠ· ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ, ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡ ΡΠ½ΠΈΡΡΠΎΠΆΠ°Π΅ΡΡΡ
std::make_shared
ΡΠ²Π»ΡΠ΅ΡΡΡ Π°Π½Π°Π»ΠΎΠ³ΠΎΠΌ std::make_unique
Π΄Π»Ρ std::shared_ptr
.
Π§ΡΠΎΠ±Ρ ΡΠ°Π·ΠΎΡΠ²Π°ΡΡ ΡΠΈΠΊΠ»ΠΈΡΠ½ΠΎΡΡΡ, Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ std::weak_ptr
[9]. ΠΡΠΎ ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠΌΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ non owning, ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½Π½ΡΠΉ Π΄Π»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ std::shared_ptr
. ΠΠΎΠΏΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ std::weak_ptr
Π½Π΅ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅Ρ ΡΡΡΡΡΠΈΠΊ Π² std::shared_ptr
, Π° Π·Π½Π°ΡΠΈΡ ΠΈ Π½Π΅ Π·Π°ΡΠΈΡΠ°Π΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΎΡ ΡΠ½ΠΈΡΡΠΎΠΆΠ΅Π½ΠΈΡ. ΠΡΠΈ ΡΡΠΎΠΌ Π²ΡΠ΅Π³Π΄Π° ΠΈΠΌΠ΅Π΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ, ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π»ΠΈ Π΅ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ, Π½Π° ΠΊΠΎΡΠΎΡΡΠΉ ΡΡΡΠ»Π°Π΅ΡΡΡ std::weak_ptr
, ΠΈΠ»ΠΈ Π½Π΅Ρ. ΠΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΊΠΎΠ΄:
class Owner {
public:
std::shared_ptr<X> owningPtr;
Owner() {
owningPtr = std::make_shared<X>();
}
};
class User {
std::weak_ptr<X> usingPtr;
public:
User(std::weak_ptr<X> object) {
usingPtr = object;
}
void use() {
if (std::shared_ptr<X> object = usingPtr.lock()) { //ΠΠΎΠΏΡΡΠΊΠ° ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΡΠΉ std::shared_ptr ΠΈΠ· std::weak_ptr, Π΅ΡΠ»ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΡΠ½ ΠΏΡΡΡΠΎΠΉ std::shared_ptr, Π·Π½Π°ΡΠΈΡ, ΠΎΠ±ΡΠ΅ΠΊΡ ΡΠΆΠ΅ Π±ΡΠ» ΡΠ΄Π°Π»ΡΠ½
object->func();
} else {
//ΠΠ±ΡΠ΅ΠΊΡ ΡΠΆΠ΅ ΡΠ΄Π°Π»ΡΠ½
}
}
};
int main() {
Owner owner;
User user(owner.owningPtr);
user.use();
}
ΠΠΎΠΎΠ±ΡΠ΅ Π³ΠΎΠ²ΠΎΡΡ, std::weak_ptr
Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π²ΡΠ΅Π³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Π½Π°Π΄ΠΎ ΡΡΡΠ»Π°ΡΡΡΡ Π½Π° ΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌΡΠΉ std::shared_ptr
ΠΎΠ±ΡΠ΅ΠΊΡ, Π½ΠΎ Π½Π΅ Π·Π°ΡΠΈΡΠ°ΡΡ Π΅Π³ΠΎ ΠΎΡ ΡΠ½ΠΈΡΡΠΎΠΆΠ΅Π½ΠΈΡ.
std::auto_ptr
[10]: Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ std::auto_ptr
. ΠΡΠΎΡ ΡΠΌΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π±ΡΠ» ΠΏΠΎΠΌΠ΅ΡΠ΅Π½ ΠΊΠ°ΠΊ ΡΡΡΠ°ΡΠ΅Π²ΡΠΈΠΉ Π² C++ 11, Π° Π² C++ 17 Π±ΡΠ» ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΡΠ΄Π°Π»ΡΠ½ ΠΈΠ· ΡΡΠ°Π½Π΄Π°ΡΡΠ° ΡΠ·ΡΠΊΠ°.ΠΡΠ²ΠΎΠ΄Ρ
ΠΠ°ΠΆΠ΄ΡΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡ Π½Π° C++ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΌΠ΅ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΌΠ½ΡΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ. Π£ΠΌΠ½ΡΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ β ΡΡΠΎ Π²Π°Ρ ΡΠΏΠΎΡΠΎΠ± ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΏΠ°ΠΌΡΡΡΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ. std::unique_ptr
β ΡΡΠΎ Π²Π°Ρ ΡΠΌΠ½ΡΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ. ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠΌΠ½ΡΡ
ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ Π½Π΅ ΠΏΡΠΎΡΠΈΠ²ΠΎΡΠ΅ΡΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΎΡΡΡΡ
ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΉ, Π² ΡΠ»ΡΡΠ°Π΅, Π΅ΡΠ»ΠΈ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ, Π° Π½Π΅ Π²Π»Π°Π΄Π΅ΡΡ ΠΈΠΌΠΈ. std::auto_ptr
β Π·Π»ΠΎ.
ΠΡΡΠΎΡΠ½ΠΈΠΊΠΈ
- https://en.cppreference.com/w/cpp/language/storage_duration
- https://en.cppreference.com/w/cpp/language/scope
- https://en.cppreference.com/w/cpp/memory/unique_ptr
- https://en.cppreference.com/w/cpp/language/throw
- https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique
- https://en.cppreference.com/w/cpp/utility/move
- https://en.cppreference.com/w/cpp/experimental/observer_ptr
- https://en.cppreference.com/w/cpp/memory/shared_ptr
- https://en.cppreference.com/w/cpp/memory/auto_ptr
- https://en.cppreference.com/w/cpp/memory/weak_ptr
ΠΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ