제목에 대해 죄송합니다. 나는 그것을 이름을 짓는 것이 확실하지 않았다. 어떤 개조사라도 독서 중이고 질문을 이해하면 필요한 경우 개명하십시오.마스터 새 변수에서 새 변수 삭제
new
변수 (varOne)를 생성한다고합시다.
varOne 코드 안에 다른 변수는 new
(varTwo, varThree)로 만들어집니다.
varOne에서 삭제를 호출하면 varTwo 및 varThree가 삭제되거나 삭제해야하며 varOne을 삭제해야합니까?
제목에 대해 죄송합니다. 나는 그것을 이름을 짓는 것이 확실하지 않았다. 어떤 개조사라도 독서 중이고 질문을 이해하면 필요한 경우 개명하십시오.마스터 새 변수에서 새 변수 삭제
new
변수 (varOne)를 생성한다고합시다.
varOne 코드 안에 다른 변수는 new
(varTwo, varThree)로 만들어집니다.
varOne에서 삭제를 호출하면 varTwo 및 varThree가 삭제되거나 삭제해야하며 varOne을 삭제해야합니까?
varOne의 소멸자를 벗어날 때 varOne의 소멸자를 호출하는 데 사용 된 삭제로 인해 varOne 인스턴스가 정리되므로 varTwo 및 varThree 만 삭제하면됩니다. 즉
, 아래의 예에서, varOne 푸이며, varTwo는 m_i이며, varThre는 m_c입니다 :
또한class Foo
{
public:
Foo() : m_i(new int), m_c(new char) { }
~Foo() { delete m_i; delete m_c; }
// don't forget to take care of copy constructor and assignment operator here!!!
private:
int* m_i;
char* m_char;
};
main()
{
Foo* p = new Foo;
delete p;
}
것은이 작업을 수행 할 때, 당신은 The Rule of Three을 따르거나 프로그램이 나빠질 수 있는지 확인 메모리 문제. (즉, 생성자에서 메모리 할당을 수행하는 경우 기본 복사 생성자 및 할당 연산자을 재정의하거나 삭제해야합니다.
별도로 varOne
을 삭제해야하지만 실제로는 varOne
의 생성자가 이러한 변수를 할당해야하며 소멸자는 어떤 이유로 든 힙에 있어야 할 경우 할당을 해제해야합니다. 값으로 저장하고 new
및 delete
을 제거하는 것이 좋습니다.
나는 당신이 의미하는 바를 100 % 확신하지는 못하지만, 일반적으로 당신이 새로운 것으로 할당 한 것은 무엇이든, 당신은 개별적으로 삭제를 해제해야합니다.
C++ 클래스의 컨텍스트에서이를 의미하는 경우 소멸자의 varOne 및 varTwo를 수동으로 삭제해야합니다.
스마트 포인터를 사용하고 자신의 코드에 아무 것도 입력하지 마십시오. delete
new
변수 (모든 변수는 정적, 자동 또는 멤버 변수)가 아니기 때문에 질문을 이해하는 방법을 모르겠지만 객체 (일반적으로 new
에서 가져 오는 포인터는 일반적으로 사용 된 변수를 초기화하려면 어쩌면 그게 무슨 뜻인가?). 따라서 귀하가 요청한 내용이 포함되어 있다는 일반 답변 광고를 보내 드리겠습니다.
먼저 기본 규칙으로 new
과 함께 할당 한 모든 개체는 delete
으로 명시 적으로 할당 해제되어야합니다. 그러나 delete
은 shared_ptr
및 scoped_ptr
/unique_ptr
(부스트는 C++ 11) 또는 auto_ptr
(더 귀여운 버전의 C++)으로 숨겨져있을 수 있습니다.
개체에 하위 개체가 포함되어있는 경우 일반적으로 개체를 직접 멤버로 만들면 new
과 함께 할당하지 않는 것이 좋습니다. 실제로 C++의 일반적인 규칙입니다. 동적으로 할당해야하는 것은 아닙니다 ,하지 마라). 즉,
class X
{
public:
// ...
private:
Type1 subobject1;
Type2 subobject2:
};
로 클래스를 써서 모두에서 하위 개체에 대한 new
/delete
엉망으로하지 않아도된다.그러나 동적으로 개체를 할당해야하는 경우 해당 개체를 삭제해야합니다 (예 :
class X
{
public:
X()
{
subobject1 = new Type1();
try
{
subobject2 = new Type2();
}
catch(...)
{
delete subobject1;
}
}
~X()
{
delete subobject2;
delete subobject1;
}
// ...
private:
X(X const&); // disabled
X& operator=(X const&); // disabled
Type1* subobject1;
Type2* subobject2;
};
주에도 예외의 경우 반드시 객체가 제대로 정리되었는지 확인하는 X
의 생성자에서 다소 복잡한 코드입니다. 또한 복사 생성 및 할당을 구현하거나 비활성화하고 비공개로 설정하여 비활성화 할 수 있습니다 (C++ 11은 비활성화하기 위해 특수 구문 = delete
을 제공합니다). 당신은 스마트 포인터를 사용하여 자신에게 문제가 많이 절약 할 수 있습니다 (하지만 당신은 여전히 적어도 일반적인 스마트 포인터, 복사 건설 및 과제에 대해 유의해야한다) :
class X
{
public:
X():
subobject1(new Type1()),
subobject2(new Type2())
{
}
private:
X(X const&) = delete; // disabled
X& operator=(X const&) = delete; // disabled
std::unique_ptr<Type1> subobject1;
std::unique_ptr<Type2> subobject2;
};
여기
내가 C 사용했습니다 ++ 11 's unique_ptr
(따라서 복사 생성자와 대입 연산자를 제거하기 위해 C++ 11 구문도 사용됩니다.) 첫 인상에이 코드에는 전혀 delete
이없는 것 같습니다. 그러나 delete
은 실제로는 소멸자 unique_ptr
에 숨겨져 있습니다. 또한 이제는 생성자에서 명시 적 예외 처리가 더 이상 필요하지 않습니다. 삭제는 unique_ptr
의 소멸자에서 수행되므로 생성자에 대한 C++의 예외 처리 규칙이 자동으로 처리됩니다.