제 생각에는 C ++의 위험이 다소 과장되어 있습니다.
C #에서는 unsafe
키워드를 사용하여 "안전하지 않은"포인터 작업을 수행 할 수 있지만 C ++ (대부분 C의 상위 집합 임)를 사용하면 필요할 때마다 포인터를 사용할 수 있습니다. 메모리 누수, 버퍼 오버플로, 댕글 링 포인터 등과 같은 포인터 (C와 동일)를 사용하는 데 따르는 일반적인 위험 외에도 C ++은 물건을 심각하게 망치는 새로운 방법을 소개합니다.
Joel Spolsky가 말한 이 "추가 로프" 는 기본적으로 한 가지로 귀결 됩니다. 내부적으로 자체 메모리를 관리하는 클래스 작성, " 3의 규칙 "(현재는 규칙이라고도 함) C ++ 11에서 4 또는 규칙 5). 즉, 자체 메모리 할당을 내부적으로 관리하는 클래스를 작성하려면 수행중인 작업을 알아야합니다. 그렇지 않으면 프로그램이 중단 될 수 있습니다. 생성자, 복사 생성자, 소멸자 및 대입 연산자를 신중하게 작성해야합니다. 이는 놀랍게도 잘못되기 쉬우 며, 종종 런타임에 이상한 충돌을 일으 킵니다.
그러나 실제로 매일의 C ++ 프로그래밍에서 자체 메모리를 관리하는 클래스를 작성하는 것은 매우 드물기 때문에 C ++ 프로그래머가 이러한 함정을 피하기 위해 항상 "주의"해야한다고 오도하는 것은 잘못입니다. 일반적으로 다음과 같은 작업을 수행하게됩니다.
class Foo
{
public:
Foo(const std::string& s)
: m_first_name(s)
{ }
private:
std::string m_first_name;
};
이 클래스는 Java 또는 C #에서 수행하는 작업과 거의 비슷해 보입니다. 라이브러리 클래스 std::string
는 자동으로 처리 하므로 명시 적 메모리 관리가 필요하지 않으며 기본값 이후 "Rule of 3"항목이 필요하지 않습니다. 복사 생성자와 할당 연산자는 괜찮습니다.
다음과 같은 일을하려고 할 때만 가능합니다.
class Foo
{
public:
Foo(const char* s)
{
std::size_t len = std::strlen(s);
m_name = new char[len + 1];
std::strcpy(m_name, s);
}
Foo(const Foo& f); // must implement proper copy constructor
Foo& operator = (const Foo& f); // must implement proper assignment operator
~Foo(); // must free resource in destructor
private:
char* m_name;
};
이 경우 초보자는 할당, 소멸자 및 복사 생성자를 올바르게 얻는 것이 까다로울 수 있습니다. 그러나 대부분의 경우이 작업을 수행 할 이유가 없습니다. C ++를 사용하면 std::string
and 같은 라이브러리 클래스를 사용하여 수동 메모리 관리 시간을 99 % 피할 수 있습니다 std::vector
.
또 다른 관련 문제는 예외가 발생할 가능성을 고려하지 않는 방식으로 메모리를 수동으로 관리하는 것입니다. 처럼:
char* s = new char[100];
some_function_which_may_throw();
/* ... */
delete[] s;
경우 some_function_which_may_throw()
실제로 않는 예외를 throw에 할당 된 메모리가 있기 때문에, 당신은 메모리 누수로 남겨 s
재생되지 않습니다. 그러나 다시 말하지만 실제로는 "3 규칙"이 더 이상 큰 문제가되지 않는 것과 같은 이유로 더 이상 문제가되지 않습니다. 원시 포인터로 실제로 자신의 메모리를 관리하는 것은 매우 드 (니다 (보통 불필요합니다). 위의 문제를 방지하려면, 당신이해야 할 것 모두가 사용할 수 있습니다 std::string
또는 std::vector
, 그리고 소멸자가 자동으로 예외가 발생 된 후 스택 언 와인딩 중에 호출받을 것입니다.
따라서 일반적인 주제는 자동 초기화 / 파괴, 복사 생성자 및 예외와 같이 C에서 상속 되지 않은 많은 C ++ 기능이 C ++ 에서 수동 메모리 관리를 수행 할 때 프로그래머가주의해야한다는 것입니다. 그러나 다시 말하지만, 처음에는 수동 메모리 관리를 수행하려는 경우에만 문제가됩니다. 표준 컨테이너와 스마트 포인터가있을 때는 더 이상 필요하지 않습니다.
따라서 C ++은 많은 추가 로프를 제공하지만 로프를 사용하여 매달릴 필요는 없으며 Joel이 말한 함정은 현대 C ++에서 피하기 쉽습니다.
Your questions should be reasonably scoped. If you can imagine an entire book that answers your question, you’re asking too much.
. 나는 이것이 그러한 질문으로 자격이 있다고 믿는다.