C ++ 14에서 new 및 delete가 여전히 유용합니까?
의 가용성을 감안할 make_unique와 make_shared에 의해뿐만 아니라 자동으로 삭제 unique_ptr및 shared_ptr소멸자 사용을 위해 (떨어져 레거시 코드를 지원에서) 상황 무엇 new과 delete++ (14) C에가?
스마트 포인터가 많은 경우 원시 포인터에 바람직하지만,에 대한 사용 사례가 많이 아직 없습니다 new/ delete14 C ++에서이.
내부 구성이 필요한 내용을 작성해야하는 경우 예를 들면 다음과 같습니다.
- 메모리 풀
- 할당 자
- 태그가 지정된 변형
- 이진 메시지를 버퍼로
배치 new및 가능하면 delete. 그럴 방법이 없습니다.
작성하려는 일부 컨테이너의 경우 저장을 위해 원시 포인터를 사용할 수 있습니다.
심지어 표준 스마트 포인터를 들어, 당신은 여전히 필요합니다 new당신이 있기 때문에 사용자 정의 deleters을 사용하려는 경우 make_unique와 make_shared그 허용하지 않습니다.
그것은 사용하는 비교적 흔한 선택 make_unique하고 make_shared오히려 원시 호출보다 new. 그러나 필수는 아닙니다. 이 규칙을 따르기로 선택했다고 가정하면 몇 군데를 사용할 수 있습니다 new.
첫째, 비 커스텀 배치 new( "비 커스텀"부분은 무시하고 배치라고 부릅니다 new)는 표준 (비 배치)와는 완전히 다른 카드 게임 new입니다. 소멸자를 수동으로 호출하는 것과 논리적으로 쌍을 이룹니다. Standard new는 무료 상점에서 리소스를 획득하고 그 안에 객체를 생성합니다. 와 쌍을 delete이루며 객체를 파괴하고 저장소를 무료 저장소로 재활용합니다. 어떤 의미에서 표준 new은 new내부적으로 배치를 delete호출 하고 표준 은 내부적으로 소멸자를 호출합니다.
배치 new는 일부 저장소에서 생성자를 직접 호출하는 방법이며 고급 수명 관리 코드에 필요합니다. 당신이 구현하는 경우 optional, 유형 안전 union정렬 스토리지에, 또는 (같은 통합 스토리지 및 비 통합 수명과 스마트 포인터를 make_shared), 당신은 위치를 사용하는 것입니다 new. 그런 다음 특정 개체의 수명이 끝나면 직접 소멸자를 호출합니다. 비 배치 같이 new하고 delete, 배치 new및 수동 소멸자 통화 쌍으로.
사용자 지정 배치는를 new사용하는 또 다른 이유 new입니다. 사용자 지정 배치 new를 사용하여 비 글로벌 풀에서 리소스를 할당 할 수 있습니다 (범위 할당 또는 교차 프로세스 공유 메모리 페이지로의 할당, 비디오 카드 공유 메모리로의 할당 등) 및 기타 목적. make_unique_from_custom커스텀 배치를 사용하여 메모리를 할당하는 것을 작성 하려면 new new키워드 를 사용해야합니다 . 사용자 지정 배치 new는 새로운 배치처럼 작동하거나 (실제로 리소스를 획득하는 것이 아니라 리소스가 어떻게 든 전달 new된다는 점에서) 표준처럼 작동 할 수 있습니다 (전달 된 인수를 사용하여 자원을 획득한다는 점에서).
커스텀 배치 delete가 발생하면 커스텀 배치 가 호출 new되므로 작성해야 할 수도 있습니다. C ++에서 사용자 지정 배치를 호출하지 않는 delete것이, (C는 ++) 을 호출 (R 과부하) .
마지막으로, make_shared그리고 make_unique그들이 정의 deleters을 지원하지 않는 점에서 불완전한 기능은 다음과 같습니다.
를 작성하는 경우 make_unique_with_deleter에도 make_unique데이터를 할당하는 데 사용할 수 있으며 삭제 자 .release()에게 고유 한 관리를 제공합니다. 삭제자가 자신의 상태를 unique_ptr별도의 할당 또는 별도의 할당 대신 지적 된 버퍼에 채우려는 경우 new여기에 배치를 사용해야 합니다.
의 경우 make_shared클라이언트 코드는 "참조 계산 스텁"생성 코드에 액세스 할 수 없습니다. 내가 말할 수있는 한 "객체 및 참조 계수 블록의 결합 된 할당"과 사용자 지정 삭제자를 모두 쉽게 가질 수는 없습니다.
또한 make_shared객체 자체에 대한 리소스 할당 (스토리지)이 지속되는 한 지속 weak_ptr되도록합니다. 어떤 경우에는 이것이 바람직하지 않을 수 있으므로 shared_ptr<T>(new T(...))이를 방지하기 위해 a 를 수행하는 것이 좋습니다.
non-placement를 호출하려는 몇 가지 경우에는을 호출 한 다음 그 와 별도로 관리하려는 경우 포인터를 new호출 할 수 있습니다 . 이렇게하면 리소스에 대한 RAII 범위가 증가하고 예외 또는 기타 논리 오류가있는 경우 유출 가능성이 줄어 듭니다.make_unique.release()unique_ptr
위에서 언급했듯이 단일 할당 블록을 쉽게 사용하는 공유 포인터가있는 사용자 지정 삭제자를 사용하는 방법을 몰랐습니다. 다음은이를 교묘하게 수행하는 방법에 대한 스케치입니다.
template<class T, class D>
struct custom_delete {
std::tuple<
std::aligned_storage< sizeof(T), alignof(T) >,
D,
bool
> data;
bool bCreated() const { return std::get<2>(data); }
void markAsCreated() { std::get<2>()=true; }
D&& d()&& { return std::get<1>(std::move(data)); }
void* buff() { return &std::get<0>(data); }
T* t() { return static_cast<T*>(static_cast<void*>(buff())); }
template<class...Ts>
explicit custom_delete(Ts...&&ts):data(
{},D(std::forward<Ts>(ts)...),false
){}
custom_delete(custom_delete&&)=default;
~custom_delete() {
if (bCreated())
std::move(*this).d()(t());
}
};
template<class T, class D, class...Ts, class dD=std::decay_t<D>>
std::shared_ptr<T> make_shared_with_deleter(
D&& d,
Ts&&... ts
) {
auto internal = std::make_shared<custom_delete<T, dD>>(std::forward<D>(d));
if (!internal) return {};
T* r = new(internal->data.buff()) T(std::forward<Ts>(ts...));
internal->markAsCreated();
return { internal, r };
}
그렇게해야한다고 생각합니다. 나는 상태 비 저장 삭제자가를 사용하여 공간을 사용하지 못하도록 허용하려고 시도 tuple했지만 실수했을 수 있습니다.
경우 라이브러리 품질의 솔루션에서 T::T(Ts...)이다 noexcept, 나는 제거 할 수 bCreatedA를 위해 더 기회가 없을 것 같은 오버 헤드를 custom_delete가 전에 파괴해야 할 T구성된다.
내가 생각할 수있는 유일한 이유는 때때로 사용자 지정 삭제자를 unique_ptr또는 shared_ptr. 사용자 지정 삭제자를 사용하려면 스마트 포인터를 직접 만들어 new. 이것은 빈번하지 않지만 실제로 발생합니다.
Other than that it seems that make_shared/make_unique should cover pretty much all uses.
I would say the only reason for new and delete is to implement other kinds of smart pointers.
For example, the library still does not have intrusive pointers as boost::intrusive_ptr, which is a pity since they are superior for performance reasons to shared pointers, as Andrei Alexandrescu points out.
참고URL : https://stackoverflow.com/questions/30762994/are-new-and-delete-still-useful-in-c14
'Program Club' 카테고리의 다른 글
| x86_64에서 정적 라이브러리를 컴파일 할 때 gcc가 암시 적으로 -fPIC 플래그를 제공하지 않는 이유 (0) | 2020.12.09 |
|---|---|
| 죽은 JavaScript 코드를 찾으십니까? (0) | 2020.12.09 |
| Mac / PC에서 글꼴 렌더링 / 줄 높이 문제 (요소 외부) (0) | 2020.12.09 |
| _BSMachError XCode 7 베타 (0) | 2020.12.09 |
| Angular ui-router : ui-views vs 디렉티브? (0) | 2020.12.09 |