C ++ 11로 전환하는 방법?


35

나는 잠시 동안 C ++로 프로그래밍 해 왔지만 대부분 C ++의 저수준 기능을 중심으로했습니다. 그것은 주로 포인터와 원시 배열로 작업하는 것을 의미합니다. 이 동작은 클래스와 함께 C ++를 C로 사용하는 것으로 알려져 있습니다. 그럼에도 불구하고, 나는 최근에 C를 처음 시도했습니다. C # 및 Java와 같은 언어가 사전 및 목록과 같은 편리한 표준 라이브러리 클래스에서 이러한 세부 정보를 숨기는 방법에 대해 놀랐습니다.

C ++ 표준 라이브러리에는 벡터, 맵 및 문자열과 같은 많은 컨테이너가 있으며 C ++ 11은 std :: array 및 ranged loops를 사용하여이를 추가합니다.

이러한 최신 언어 기능을 사용하고 어떤 순간에 적합한 지 가장 잘 배우는 방법은 무엇입니까? 오늘날 C ++의 소프트웨어 엔지니어링에 대부분 수동 메모리 관리가없는 것이 맞습니까?

마지막으로, 새로운 표준을 최대한 활용하기 위해 어떤 컴파일러를 사용해야합니까? Visual Studio에는 뛰어난 디버깅 도구가 있지만 VS2012조차도 끔찍한 C ++ 11을 지원하는 것 같습니다.


2
VS2012의 C ++ 11 지원을 "끔찍한"이라고 부르는 것은 다소 과장되었지만 확실히 더 좋을 수 있습니다 (이니셜 라이저 목록을 누락하면 테스트 / 장난감 코드가 특히 성가시다). 그러나 이들은 나머지 VS와 독립적으로 컴파일러 업데이트를 제공 할 것이라고 발표 했으므로 2013 년에 VS2012의 C ++ 11 기능이 상당히 많을 것으로 기대합니다.
Martin Ba

3
처음에는 C ++ 11을 배우는 것이 이상하다고 생각했지만 C-With-Classes 땅 에 여전히 붙어있는 것을 보았습니다 ... 10 년 전 Koenig / Moo의 Accelerated C ++를 읽었습니다 . 실제로 이미 템플릿 메타 프로그래밍을 수행하고 있었지만 (검토 용으로 만 읽음) 여전히 계시처럼 느껴졌습니다. (저는 그 이후로 C ++을 가르치기위한 기반으로 사용했습니다.) C에서 시작하는 클래스를 통해이 책은 당신이 당신이 처분 할 줄 몰랐던 완전히 새로운 언어를 보여줄 수 있습니다. 250 페이지에 불과하며 C ++ 11 전용으로 빠르게 발전 할 수 있지만 IMO는 가치있는 단계입니다.
sbi

4
g++ -std=c++11
fredoverflow

답변:


50

먼저, 몇 가지 경험 법칙 :

  • std::unique_ptr오버 헤드없는 스마트 포인터로 사용하십시오 . 원시 포인터를 자주 사용하지 않아도됩니다. std::shared_ptr대부분의 경우에도 마찬가지입니다. 공유 소유권에 대한 욕구는 종종 소유권에 대한 생각 부족을 배신합니다.

  • 사용하여 std::array고정 길이 배열과 std::vector동적하십시오.

  • 다음과 같은 일반적인 알고리즘을 광범위하게 사용하십시오.

    • <algorithm>
    • <numeric>
    • <iterator>
    • <functional>
  • 사용 auto하고 decltype()어디서든 가독성을 혜택을 누릴 수 있습니다. 특히, 일을 선언하고 싶지만 반복 자나 복잡한 템플릿 유형과 같이 신경 쓰지 않는 유형의 경우을 사용하십시오 auto. 다른 사물의 유형으로 사물을 선언하려면을 사용하십시오 decltype().

  • 가능하면 물건을 안전하게 보관하십시오. 특정 종류의 일에 대해 불변을 적용하는 주장이있는 경우 해당 논리를 유형으로 중앙 집중화 할 수 있습니다. 그리고 이것이 반드시 런타임 오버 헤드를 유발하지는 않습니다. 또한 C 스타일 캐스트 ( (T)x)는보다 명시적인 (및 검색 가능한) C ++ 스타일 캐스트 (예 :)를 선호하지 않아야합니다 static_cast.

  • 마지막으로 세 가지 규칙이 어떻게되는지 아십시오.

    • 파괴 장치
    • 생성자 복사
    • 할당 연산자

    이동 생성자와 이동 대입 연산자를 추가하여 5의 규칙이되었습니다. 그리고 일반적으로 rvalue 참조와 복사를 피하는 방법을 이해하십시오.

그것을 가장 잘 사용하는 방법을 특성화하기 어려운, 그래서 C ++은 복잡한 언어 모든 그것의를. 그러나 좋은 C ++ 개발의 관행은 C ++ 11에서 근본적으로 바뀌지 않았습니다. 수동 메모리 관리보다 메모리 관리 컨테이너를 선호해야합니다. 스마트 포인터를 사용하면이를 효율적으로 수행 할 수 있습니다.

현대 C ++에는 실제로 수동 메모리 관리가 거의 없다고 말하고 싶습니다. C ++의 메모리 모델의 장점은 수동이 아니라 결정적 이라는 것입니다. 예측 가능한 할당 해제는보다 예측 가능한 성능을 제공합니다.

컴파일러의 경우, G ++ 및 Clang은 C ++ 11 기능 측면에서 경쟁력이 있으며 결함을 빠르게 따라 잡습니다. Visual Studio를 사용하지 않으므로 말하거나 반대 할 수 없습니다.

마지막으로, std::for_each일반적으로 피하십시오.

transform, accumulate,와 erase- remove_if기능 옛 좋은 map, fold그리고 filter. 그러나 for_each더 일반적이고 의미가 덜 합니다. 루핑 이외의 의도 는 표현하지 않습니다 . 게다가, 그것은 range-based와 같은 상황에서 사용되며, for포인트 프리를 사용하더라도 구문 적으로 더 무겁습니다. 치다:

for (const auto i : container)
    std::cout << i << '\n';

std::for_each(container.begin(), container.end(), [](int i) {
    std::cout << i << '\n';
});

for (const auto i : container)
    frobnicate(i);

std::for_each(container.begin(), container.end(), frobnicate);

6
이러한 경험 규칙에 구속력있는 원칙이 있습니까? 그것은 좋은 제안 목록처럼 보이지만 ... Google을 통해이 질문에 도착하는 외부인으로서 귀하의 답변은 원칙적으로 C ++ 11을 집어 들고 C ++ 차축을 감싸지 않고 사용하는 데 어떻게 도움이됩니까? ?
Robert Harvey

3
목록에 +1이지만 작은 nitpick이 있습니다. 경고에 대해 (정확하게) 경고 할 때 std::for_each평문보다 더 나은 대체로 루프 기반 범위를 예상했을 것 for입니다.
Fabio Fracassi

@ FabioFracassi : 죄송합니다. 내가 쓴 일반 과 대조 할 수 std::for_each없습니다로, 범위 기반 . 혼란을 피하기 위해 제거했습니다.
Jon Purdy

1
이 아닌 경우 업데이트합니다 std::for_each(). 람다가 있으면 전통적인 for루프 보다 낫습니다 . for그렇지 않을 수도 있는 범위 기반 루프를 사용하지만 "범위 기반 for루프"를 작성하지 않았습니다 .
sbi

@ sbi : 내 생각에“ for루프” 라는 용어 에는“범위 기반 for루프”가 포함됩니다. 좀 더 설명하고 명확하게 설명하는 예제로 편집했습니다. 감사합니다.
Jon Purdy

12

출발점으로 :

  • char*문자열 사용 을 중지하십시오 . 코드를 더 짧고, 더 읽기 쉽고, 안전하게 사용 std::string하거나 std::wstring보고
  • C 스타일 배열 (으로 선언 된 것 [ ]) 사용을 중지 std::vector하고 다른 적절한 컨테이너 클래스를 사용하십시오. 좋은 std::vector점은 자체 길이를 알고 범위를 벗어날 때 내용을 정리하고 반복하기 쉽고 항목을 추가 할 때 더 커진다는 것입니다. 그러나 상황에 따라 더 잘 작동 할 수있는 다른 컬렉션이 있습니다.
  • 사용 std::unique_ptr하고 std::move거의 즉시 배웁니다 . 이 몇 가지 noncopyable 객체가 발생할 수 있기 때문에, 게으름은 때때로 당신으로 보낼 수 있습니다 std::shared_ptr- 당신은 몇 가지 정품 사용 사례가있을 수 std::shared_ptr뿐만 아니라를
  • auto이전 선언에 의존하는 반복자와 유형을 선언 할 때 사용하십시오 (예 : 이전에 무언가의 벡터를 선언했습니다. 이제 무언가를 선언하고 사용하십시오 auto)
  • for_each다른 사람들이 루프를주의 깊게 읽지 않아도되므로 실제로 전체 컬렉션 등을 반복한다고 결론을 내릴 수 있기 때문에 알고리즘과 "raw for"를 사용하십시오 for_each. 컴파일러가 "range"를 지원하는 경우이를 사용하십시오 . 같은 사소한 알고리즘을 호출 알아 iota, generate, accumulate, find_if등을.
  • 람다 사용-알고리즘을 쉽게 활용할 수있는 방법입니다. 그들은 또한 훨씬 더 많은 문을 엽니 다.

사용할 컴파일러에 대해 너무 신경 쓰지 마십시오. VS2012의 C ++ 11 지원에 대한 "끔찍하고 끔찍한"부족은 가변 템플릿이없고 (예, 가변 템플릿을 사용 하려고 했지만) {}이니셜 라이저가 없다는 것입니다. 나도 그것을 원하지만 유용한 개발 도구를 사용하는 것을 멈추지 않을 것입니다.

수용 후 두 번째로해야 할 일은 std::RAII를 생각하는 것입니다. 당신은 언제든지

  • 행동 시작
  • 액션을 시작하여 얻은 일련의 액션
  • 예외의 경우에도 발생해야하는 정리 조치

그런 다음 생성자, 여러 멤버 함수 및 소멸자가 있습니다. 당신을 위해 그것을 돌보는 수업을 작성하십시오. ctor와 dtor를 쓰지 않아도됩니다. shared_ptr클래스의 멤버 변수로 a를 넣는 것은 RAII의 예입니다. 메모리 관리 코드를 작성하지 않지만 인스턴스가 범위를 벗어나면 올바른 일이 발생합니다. 파일 닫기, 핸들 해제, 잠금 해제 등과 같은 것들을 포함하도록 생각을 넓히면 코드가 눈 앞에서 간단하고 작아집니다 (누설을 제거하면서).

당신이 정말로 자신감이 있다면, printf에 찬성하여 cout제거하고, 매크로를 제거 #define하고, PIMPL과 같은 "고급 관용구"를 배우기 시작하십시오. Pluralsight에서는 무료 평가판을 사용하여 볼 수 있는 전체 과정을 제공합니다 .


2
나는 variadic 템플릿을 언제라도 사용하지 않는 것에 대해 냉소적 인 방법을 좋아하지만 균일 한 초기화 누락이 일상적인 프로그래밍에 실제로 중요한 것이 누락 된 것으로 생각합니다.
sbi

이니셜 라이저 목록을 기다릴 수 없습니다 ... 언제 우리가 얻을 수 있는지 알아보기 위해 기다리는 중 ...
Kate Gregory

VS2012의 또 다른 중요한 결점은 "rvalue reference v3", 즉 자동 생성 된 이동 생성자 및 이동 할당입니다.
Mr.C64

3

이러한 최신 언어 기능을 사용하고 어떤 순간에 적합한 지 가장 잘 배우는 방법은 무엇입니까?

프로그래밍으로. 경험은 배우는 가장 좋은 방법입니다.

C ++ 11에는 많은 새로운 기능 (자동, rvalue, 새로운 스마트 포인터)이 있습니다. 가장 좋은 시작은 사용을 시작하고 가능할 때마다 그리고 흥미로운 기사를 찾을 때마다 그 내용을 읽는 것입니다.

오늘날 C ++의 소프트웨어 엔지니어링에 대부분 수동 메모리 관리가없는 것이 맞습니까?

그것은 당신이해야 할 일에 달려 있습니다. 대부분의 응용 프로그램은 스마트 포인터를 사용하지 않고 메모리 관리를 잊을 수 있습니다. 쉽게 벗어날 수없는 응용 프로그램이 여전히 있습니다 (예 : 새로운 배치 또는 사용자 지정 메모리 할당자가 필요한 경우).

Qt를 사용해야하는 경우 메모리 관리에 규칙을 사용해야합니다.

새로운 표준을 최대한 활용하려면 어떤 컴파일러를 사용해야합니까?

최신 표준을 지원하는 모든 기능 :

그러나 모든 기능을 지원하는 컴파일러는 없습니다.


-7

우리 대학은 여전히 ​​가르치기 위해 C ++을 사용하고 있습니다. 저는 5 년 동안 C ++로 프로그래밍했으며 현재 대학원생입니다. 물론 지금은 많은 Java, Ruby 등을 사용하고 있습니다. Java와 같은 언어의 기능에 대해 서두르지 않는 것이 좋습니다. 저의 경험과 의견으로는 C ++의 저수준 기능 후에. 템플릿 클래스, 템플릿 함수, 연산자 재정의, 가상 메서드, 스마트 포인터 만들기와 같은 C / C ++를 사용한 일반 프로그래밍과 같은 주제를 살펴 봐야합니다. Object Oriented Design Part에는 C ++의 많은 기능이 있으며 Java는 다중 상속과 같은 기능을 제공하지 않습니다. 상속은 강력하지만 위험합니다. C ++에서 객체 지향 디자인의 구현 수준도 좋은 주제입니다. 프로세스 간 통신, 스레딩은 C ++에서도 중요합니다.

컴파일러와 디버거 Visual Studio가 훌륭하다는 것을 알고 있습니다. 그러나 GDB, Valgrind 및 Make still을 배우고이 도구를 능숙하게 사용하는 것이 좋습니다. Microsoft는 훌륭하지만 너무 많은 일을했습니다. 학생으로서, Microsoft도 귀하가 한 일을 실제로 배워야합니다. 컴파일러의 경우 G ++은 GNU에서 우수합니다.

결국, 수년이 지난 지금, 가장 중요한 것은 원시 배열과 같은 저수준 기능입니다. 벡터는 실제로 동적 배열입니다. 이것들은 내가 추천하는 것, 너무 주관적인 것, 옳다고 생각하는 것을 취하십시오.


6
이 질문에 어떻게 대답합니까? 문제는 일반적인 C ++ 학습에 관한 것이 아니라 C ++ 11로 전환하는 것입니다.
Roc Martí
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.