C ++ 11로 전환하는 방법? 불구하고, 나는 최근에

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

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

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

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



답변

먼저, 몇 가지 경험 법칙 :

  • 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,와 eraseremove_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);

답변

출발점으로 :

  • 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에서는 무료 평가판을 사용하여 볼 수 있는 전체 과정을 제공합니다 .


답변

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

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

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

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

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

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

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

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

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


답변

우리 대학은 여전히 ​​가르치기 위해 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에서 우수합니다.

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