C ++에서 C로 이동


83

몇 년 동안 C ++로 코딩 한 후 최근 임베디드 분야에서 C로 코딩하는 작업을 제안 받았습니다.

임베디드 필드에서 C ++를 무시하는 것이 옳은지 그른지에 대한 질문을 제쳐두고 C ++에는 몇 가지 기능 / 관용구가 있습니다. 몇가지 말하자면:

  • 일반 형식이 안전한 데이터 구조 (템플릿 사용).
  • RAII. 특히 여러 리턴 포인트가있는 함수에서, 예를 들어 각 리턴 포인트에서 뮤텍스를 해제하는 것을 기억할 필요가 없습니다.
  • 일반적으로 소멸자. 즉, MyClass에 대해 d' tor를 한 번 작성하면 MyClass 인스턴스가 MyOtherClass의 멤버 인 경우 MyOtherClass는 MyClass 인스턴스를 명시 적으로 초기화 할 필요가 없습니다. 해당 d' tor는 자동으로 호출됩니다.
  • 네임 스페이스.

C ++에서 C로 전환 한 경험은 무엇입니까?
좋아하는 C ++ 기능 / 관용구를 대체하는 C는 무엇입니까? C ++에 원하는 C 기능을 발견 했습니까?


12
조언이 아닌 경험을 요구하는 경우 커뮤니티 위키 일 것입니다.
Peter Alexander

6
Prog.SE에 관심이있을 수 있습니다 .

11
@Peter : OP는 더 이상 질문을 CW로 만들 수 없으며 여전히 가능했을 때보 다 더 많은 담당자가 필요했습니다. 더 많은 사용자가 "커뮤니티 소유"게시물을 편집 할 수 있도록 허용하는 것 외에 다른 이유로 질문을 커뮤니티 위키로 만들어야한다고 생각한다면 질문을 닫는 것이 좋습니다.

4
이 질문이 programmers.se에 더 적합하지 않을까요? 확실히 "진짜"질문이기 때문에 다시 열어 대신 투표를하겠습니다. 그리고 그것은 불가능합니다. 확인.
Lasse V. Karlsen

21
프로그램 SE가 베타가 종료 될 때까지 이동은 일어나지 않을 것이며, 어떤 경우에도 QA에 대한이 접근 방식은 브레인 데드를 망가 뜨리는 것이라고 생각합니다. 커뮤니티를 분열시키고 사용자를 짜증나게하며 질문과 답변을 복제합니다. 이전에는 단일 "프로그래머"사이트에서 액세스하고 탐색 할 수 있었던 조직화되지 않은 정보의 혼란을 일으키고 있습니다. 또한, 거대한 견해와 놀라운 찬성 투표를 가진 이와 같은 질문이 5 명을 더 가까이에서 쫓아내는 것과 커뮤니티 전체 사이에서 화가 나게 만듭니다.
Stefano Borini

답변:


68

임베디드 프로젝트에서 작업하면서 모든 C로 한 번 작업을 시도했지만 참을 수 없었습니다. 너무 장황해서 아무것도 읽기가 어려웠습니다. 또한 내가 작성한 내장 컨테이너에 최적화 된 것이 마음에 들었습니다.이 컨테이너는 훨씬 덜 안전하고 #define블록 을 수정하기가 더 어렵습니다 .

C ++의 코드는 다음과 같습니다.

if(uart[0]->Send(pktQueue.Top(), sizeof(Packet)))
    pktQueue.Dequeue(1);

다음으로 바뀝니다.

if(UART_uchar_SendBlock(uart[0], Queue_Packet_Top(pktQueue), sizeof(Packet)))
    Queue_Packet_Dequeue(pktQueue, 1);

많은 사람들이 아마 괜찮다고 말 하겠지만 한 줄에 두 번 이상의 "방법"호출을해야한다면 우스꽝스러워집니다. 두 줄의 C ++는 80 자의 줄 길이 제한으로 인해 C의 다섯 줄로 바뀝니다. 둘 다 동일한 코드를 생성하므로 대상 프로세서가 신경 쓰지 않습니다!

한 번은 (1995 년) 다중 프로세서 데이터 처리 프로그램을 위해 많은 C를 작성하려고했습니다. 각 프로세서에 자체 메모리와 프로그램이있는 종류입니다. 공급 업체에서 제공 한 컴파일러는 C 컴파일러 (일종의 HighC 파생물) 였고 라이브러리는 폐쇄 된 소스 였기 때문에 GCC를 사용하여 빌드 할 수 없었으며 API는 프로그램이 주로 초기화 / 프로세스가 될 것이라는 사고 방식으로 설계되었습니다. / 종결 다양성, 그래서 프로세서 간 통신은 기껏해야 초보적이었습니다.

포기하기 약 한 달 전에 cfront 사본을 찾았습니다. C ++를 사용할 수 있도록 makefile에 해킹했습니다. Cfront는 템플릿도 지원하지 않았지만 C ++ 코드는 훨씬 더 명확했습니다.

일반 형식이 안전한 데이터 구조 (템플릿 사용).

C가 템플릿에 가장 가까운 것은 다음과 같은 많은 코드로 헤더 파일을 선언하는 것입니다.

TYPE * Queue_##TYPE##_Top(Queue_##TYPE##* const this)
{ /* ... */ }

그런 다음 다음과 같이 가져옵니다.

#define TYPE Packet
#include "Queue.h"
#undef TYPE

처음 unsigned char만들지 않는 한 복합 유형 (예 :의 대기열 없음 ) 에는 작동하지 않습니다 typedef.

아, 그리고이 코드가 실제로 어디에도 사용되지 않는다면 구문 상 올바른지조차 알지 못합니다.

편집 : 한 가지 더 : 코드 인스턴스화 를 수동으로 관리 해야 합니다. "템플릿"코드가 모두 인라인 함수 가 아닌 경우 , 링커가 "다중 Foo 인스턴스"오류를 뱉어 내지 않도록 한 번만 인스턴스화되도록 일부 제어를해야합니다. .

이렇게하려면 헤더 파일의 "구현"섹션에 인라인되지 않은 항목을 넣어야합니다.

#ifdef implementation_##TYPE

/* Non-inlines, "static members", global definitions, etc. go here. */

#endif

그런 다음 템플릿 변형 당 모든 코드의 곳에서 다음 을 수행해야합니다.

#define TYPE Packet
#define implementation_Packet
#include "Queue.h"
#undef TYPE

또한이 구현 섹션 은 다른 헤더 파일에 템플릿 헤더 파일을 포함 할 수 있지만 나중에 파일 에서 인스턴스화해야하기 때문에 표준 / / litany 외부 에 있어야 합니다.#ifndef#define#endif.c

네, 추악하게 빠르게됩니다. 그래서 대부분의 C 프로그래머는 시도조차하지 않습니다.

RAII.

특히 여러 리턴 포인트가있는 함수에서, 예를 들어 각 리턴 포인트에서 뮤텍스를 해제하는 것을 기억할 필요가 없습니다.

음, 예쁜 코드를 잊고 (함수의 끝 제외) 모든 반환 지점에 익숙해 goto들 :

TYPE * Queue_##TYPE##_Top(Queue_##TYPE##* const this)
{
    TYPE * result;
    Mutex_Lock(this->lock);
    if(this->head == this->tail)
    {
        result = 0;
        goto Queue_##TYPE##_Top_exit:;
    }

    /* Figure out `result` for real, then fall through to... */

Queue_##TYPE##_Top_exit:
    Mutex_Lock(this->lock);
    return result;
}

일반적으로 소멸자.

즉, MyClass에 대해 d' tor를 한 번 작성하면 MyClass 인스턴스가 MyOtherClass의 멤버 인 경우 MyOtherClass는 MyClass 인스턴스를 명시 적으로 초기화 할 필요가 없습니다. 해당 d' tor는 자동으로 호출됩니다.

객체 생성은 동일한 방식으로 명시 적으로 처리되어야합니다.

네임 스페이스.

그것은 실제로 고치기 쉬운 것 입니다. 모든 심볼에 접두사를 붙이기 만하면 됩니다 . 이것이 제가 이전에 이야기했던 소스 팽창의 주요 원인입니다 (클래스는 암시 적 네임 스페이스이기 때문입니다). C 사람들은 이것을 영원히 살았고 아마도 큰 문제가 무엇인지 알지 못할 것입니다.

YMMV


59
물론 C를 강제로 C ++로 만들려고하면 C를 싫어합니다. $ more_expressive_language의 기능을 적용하려고하면 C ++가 멋지게 보일 것 같지 않습니다. 귀하의 게시물에 대한 비판이 아니라 관찰 일뿐입니다. :-)

RII 대신 goto 기술 : 유지 보수의 악몽이 아닙니까? 즉 정리가 필요한 코드 경로를 추가하거나 함수 내부의 순서를 변경할 때마다 마지막에있는 goto 레이블로 이동하여 변경해야합니다. 정리해야 할 항목 바로 옆에 정리 코드를 어떻게 든 등록하는 기술을보고 싶습니다.
조지

2
@george : 나는 그것을 말하기 싫지만 내가 본 대부분의 임베디드 C 코드는 C 표준에 의해 상당히 나쁩니다. 예를 들어, 저는 지금 Atmel의 at91lib로 작업하고 있으며 대부분의 코드가 종속성으로 가져 오는 "board.h"파일을 작성해야합니다. (데모 보드의 경우이 헤더의 길이는 792 행입니다.) 또한 보드에 맞게 사용자 정의해야하는 "LowLevelInit ()"함수는 거의 전적으로 등록 액세스입니다. 다음과 같은 행이 있습니다AT91C_BASE_PMC->PMC_MOR = (0x37 << 16) | BOARD_OSCOUNT | AT91C_CKGR_MOSCRCEN | AT91C_CKGR_MOSCXTEN | AT91C_CKGR_MOSCSEL;
Mike DeSimone

1
당신이이 이야기 아, 그리고 아무것도 BOARD_OSCOUNT(스위치 시계를 기다리고에 대한 타임 아웃 값이다;? 분명, 허)는 실제로 없습니다 #defineboard.h. 또한 동일한 기능에는 복사하여 붙여 넣은 많은 스핀 루프 코드가 있습니다.이 코드는 두 줄로 #define바뀌어야합니다. 레지스터 세트와 스핀 루프를 더 뚜렷하게 만들어서 더 읽기 쉬운 기능). C를 사용하는 가장 큰 이유 중 하나는 모든 것을 세부적으로 관리하고 최적화 할 수 있다는 것입니다.하지만 제가 본 대부분의 코드는 신경 쓰지 않습니다.
Mike DeSimone

5
@Mads에 동의합니다. 실제로 필요하지 않은 기능에 대해 모든 것을 검토 할 이유가 없습니다. GTK 라이브러리와 비슷한 스타일을 좋아합니다. "클래스"를 구조체로 정의한 다음 my_class_new ()와 같은 일관된 메서드를 만든 다음 "methods"에 전달합니다. my_class_do_this (my_class_instance)
Max

17

나는 다른 이유로 (알레르기 반응의 일종) C ++에서 C로 옮겼고, 내가 놓친 것은 몇 가지 뿐이고 얻은 것들은 몇 가지뿐입니다. C99를 고수한다면, 가능하다면 아주 멋지고 안전하게 프로그래밍 할 수있는 구조가 있습니다. 특히

  • 지정된 이니셜 라이저 (결국 매크로와 결합 됨)는 간단한 클래스를 생성자처럼 쉽게 초기화합니다.
  • 임시 변수에 대한 복합 리터럴
  • for-scope 변수는 범위 바운드 리소스 관리 를 수행하는 데 도움이 될 수 있습니다 . 특히 unlock뮤텍스 또는free 예비 함수 반환 하에서도 배열 합니다.
  • __VA_ARGS__ 매크로를 사용하여 함수에 대한 기본 인수를 갖고 코드 언 롤링을 수행 할 수 있습니다.
  • inline (일종의) 오버로드 된 함수를 대체하기 위해 잘 결합 된 함수 및 매크로

2
@Mike : 특히 어떤 부분에 대해? for스코프에 대해 제공 한 링크를 따라 가면 P99에 도달하게되며, 여기에서 다른 부분의 예제와 설명도 살펴볼 수 있습니다.
Jens Gustedt 2010 년


@george : 감사합니다! @Jens : 다른 4 개의 예. 나는 내 C에서 뒤쳐졌다. 나는 그들이 런타임 크기의 자동 할당 (즉, 스택) 배열 (예를 들어 추가 들었다 지속 void DoSomething(unsigned char* buf, size_t bufSize) { unsigned char temp[bufSize]; ... }(예를 들어, 필드 이름에 의해)과 구조 초기화 struct Foo bar = { .field1 = 5, .field2 = 10 };) (예를, 나는 C ++로보고 싶어요하는 후자 특히 비 POD는 객체를 UART uart[2] = { UART(0x378), UART(0x278) };) .
Mike DeSimone

@Mike : 예, 가변 길이 배열 (VLA)이 있지만 잠재적 인 스택 오버 플로우로 인해 사용하기에 약간 위험 할 수 있습니다. 당신이 설명하는 두 번째는 정확히 "지정된 이니셜 라이저"입니다. 그래서 당신은 당신 자신의 예제와 함께갑니다 ;-) 다른 사람들의 경우 "관련 페이지"를 클릭하면 위의 P99 링크에서 정보를 찾을 수 있습니다.
Jens Gustedt

8

C에는 STL과 같은 것이 없습니다.
유사한 기능을 제공하는 라이브러리가 있지만 더 이상 내장되어 있지 않습니다.

이것이 내 가장 큰 문제 중 하나라고 생각합니다. 어떤 도구로 문제를 해결할 수 있는지 알고 있지만 사용해야하는 언어로 도구를 사용할 수 없습니다.


이것은 사실입니다. 누구든지 C에 어떤 컨테이너 클래스 라이브러리를 사용 해야하는지 자세히 설명 할 수 있습니까? 아니면 대답은 "직접 작성"입니까?
Sandeep

@Sandeep : 우선,이 대답은 컨테이너가 표준 라이브러리에없는 경우에만 옳습니다. STL (C ++의 가장 좋은 부분)이없는 것 외에도 C 표준 라이브러리가 훨씬 우수합니다. POSIX에는 libc에있는 qsort 외에 tsearch, lsearch, hsearch 및 bsearch가 포함됩니다. Glib는 C의 확실한 "부스트"입니다. 여기에 좋은 기능이 포함되어 있습니다 (컨테이너 포함). library.gnome.org/devel/glib/stable . Glib는 Boost와 Qt를 능가하는 Gtk + 와도 통합됩니다. Subversion 및 Apache와 같은 xplatform 항목에 인기있는 libapr도 있습니다.
Matt Joiner

stl과 경쟁 할 수있는 c의 라이브러리를 찾을 수 없으며 사용하기가 더 어렵고 유지 관리가 더 어렵고 성능이 stl과 같은 일반 라이브러리를 유지하려는 경우 stl의 라이벌이 아닙니다. c의 한계와 c 라이브러리에서 stl과 같은 것을 가질 수없는 이유. c는 단순히 stl과 같은 것을 개발할 능력이 없기 때문입니다.
StereoMatching

8

C와 C ++의 차이점은 코드 동작의 예측 가능성입니다.

C에서 코드가 수행 할 작업을 매우 정확하게 예측하는 것이 더 쉬우 며, C ++에서는 정확한 예측을내는 것이 조금 더 어려울 수 있습니다.

C의 예측 가능성은 코드가 수행하는 작업을 더 잘 제어 할 수있게 해주지 만 더 많은 작업을 수행해야 함을 의미합니다.

C ++에서는 동일한 작업을 수행하기 위해 더 적은 코드를 작성할 수 있지만 (나를 위해) 가끔 객체 코드가 메모리에 배치되는 방식과 예상되는 동작을 아는 데 어려움이 있습니다.


4
코드가 실제로 수행하는 작업에 대해 걱정할 때마다 -s플래그를 추가 gcc하여 어셈블리 덤프를 가져오고 관심있는 기능을 검색하고 읽기를 시작합니다. 컴파일 된 언어의 특성을 배울 수있는 좋은 방법입니다.
Mike DeSimone

2
C ++에서 생성 된 어셈블리가 Perl을 읽는 것과 같기 때문에 시간 낭비이기도합니다. 어쨌든 브라보.
Matt Joiner

7

그건 그렇고, 내 작업 라인에서 나는 C와 C ++ 사이를 끊임없이 앞뒤로 전환하고 있습니다.

C에있을 때 C ++에서 그리워합니다.

  • 템플릿 (STL 컨테이너를 포함하되 이에 국한되지 않음). 특수 카운터, 버퍼 풀 등과 같은 작업에 사용합니다 (다른 임베디드 프로젝트에서 사용하는 클래스 템플릿 및 함수 템플릿 라이브러리를 구축했습니다).

  • 매우 강력한 표준 라이브러리

  • 물론 RAII를 가능하게하는 소멸자 (뮤텍스, 인터럽트 비활성화, 추적 등)

  • 액세스 지정자를 사용하여 누가 무엇을 사용할 수 있는지 (볼 수 없음)

나는 더 큰 프로젝트에서 상속을 사용하고, C ++의 내장 지원은 기본 클래스를 첫 번째 멤버로 포함하는 C "해킹"보다 훨씬 깨끗하고 멋집니다 (생성자, 초기화 목록 등의 자동 호출은 말할 것도 없습니다. ) 그러나 위에 나열된 항목은 내가 가장 그리워하는 항목입니다.

또한 사용 예외에 대해 작업하는 임베디드 C ++ 프로젝트의 1/3 정도에 불과하므로 예외없이 생활하는 데 익숙해 져서 C로 돌아갈 때 너무 그리워하지 않습니다.

반대로 상당수의 개발자가 참여하는 C 프로젝트로 돌아 가면 사라지는 사람들에게 설명하는 데 익숙한 전체 클래스의 C ++ 문제가 있습니다. 대부분 C ++의 복잡성으로 인한 문제와 무슨 일이 일어나고 있는지 알고 있다고 생각하지만 실제로는 C ++ 신뢰 곡선 의 "C with classes"부분에 있습니다. 있습니다.

선택권이 주어지면 프로젝트에서 C ++를 사용하는 것을 선호하지만 팀이 언어에 대해 상당히 견실 한 경우에만 가능합니다. 물론 제가 "C"를 효과적으로 작성하고있는 8K μC 프로젝트가 아니라고 가정합니다.


2
그 "C ++ Confidence Curve"는 나를 조금 괴롭 힙니다. 쓰여진 방식과 주석은 C ++가 절망적이거나 잃어버린 원인 등을 의미합니다. 내가 뭔가를 놓치고 있습니까?
Mike DeSimone

뛰어 내리면 몇 년 후에 뵙겠습니다. 대부분의 훌륭한 프로그래머는 반대편에서 신맛을냅니다.
Matt Joiner

3

몇 가지 관찰

  • C ++ 컴파일러를 사용하여 C를 빌드 할 계획이 아니라면 (C ++의 잘 정의 된 하위 집합을 고수하는 경우 가능함) 곧 컴파일러가 C에서 허용하는 C ++의 컴파일 오류를 발견하게됩니다.
  • 더 이상 모호한 템플릿 오류가 없습니다 (예!)
  • (지원되는 언어) 객체 지향 프로그래밍 없음

C는 템플릿을 지원하지 않는다고해서 "일반 패러다임"이 필요하지 않다는 의미는 아닙니다. C에서는 "일반 패러다임"이 필요한 경우 템플릿을 모방하기 위해 void * 및 매크로를 사용해야합니다. void *는 형식에 안전하지 않습니다. 매크로 오류 또한 템플릿보다 낫지 않은 꽤 엉뚱한 데 템플릿은 매크로보다 읽고 유지하기가 훨씬 쉽고 형식에 안전합니다.
StereoMatching

2

순수한 C가 아닌 C ++ 또는 C / C ++ 혼합을 사용하는 것과 거의 동일한 이유입니다. 네임 스페이스 없이도 살 수 있지만 코드 표준에서 허용하는 경우 항상 사용합니다. 그 이유는 C ++로 훨씬 더 간결한 코드를 작성할 수 있기 때문입니다. 이것은 나에게 매우 유용합니다. 저는 가끔 충돌하는 경향이있는 C ++로 서버를 작성합니다. 이 시점에서보고있는 코드가 짧고 구성되어 있으면 많은 도움이됩니다. 예를 들어 다음 코드를 고려하십시오.

uint32_t 
ScoreList::FindHighScore(
  uint32_t p_PlayerId)
{
  MutexLock lock(m_Lock); 

  uint32_t highScore = 0; 
  for(int i = 0; i < m_Players.Size(); i++)
  {
    Player& player = m_Players[i]; 
    if(player.m_Score > highScore)
      highScore = player.m_Score; 
  }

  return highScore; 
}

C에서 다음과 같이 보입니다.

uint32_t 
ScoreList_getHighScore(
  ScoreList* p_ScoreList)
{
  uint32_t highScore = 0; 

  Mutex_Lock(p_ScoreList->m_Lock); 

  for(int i = 0; i < Array_GetSize(p_ScoreList->m_Players); i++)
  {
    Player* player = p_ScoreList->m_Players[i]; 
    if(player->m_Score > highScore)
      highScore = player->m_Score; 
  }

  Mutex_UnLock(p_ScoreList->m_Lock);

  return highScore; 
}

차이의 세계가 아닙니다. 한 줄의 코드가 더해 지지만 그것은 합쳐지는 경향이 있습니다. 일반적으로 깨끗하고 가늘게 유지하기 위해 최선을 다하지만 때로는 더 복잡한 작업을해야합니다. 그리고 그러한 상황에서 당신은 당신의 라인 수를 중요하게 생각합니다. 한 줄 더는 브로드 캐스트 네트워크가 갑자기 메시지 전달을 중단하는 이유를 알아 내려고 할 때 살펴 봐야 할 또 하나입니다.

어쨌든 C ++를 사용하면 안전한 방식으로 더 복잡한 작업을 수행 할 수 있습니다.


C에서는 "for (int i = 0")를 수행 할 수 없습니다.
Victor

6
Victor는 유효한 c99입니다 (또는 일부 타이핑 문제에 대해 C ++ 컴파일러로 c를 컴파일).
Roman A. Taycher 2010 년

나는 안전을 믿을 수 없다는 것을 안다. 따라서 뮤텍스는 범위가 지정됩니다. 이제 예외가 "방황"해야하는 이유를 알 수 없습니다. 언제 잠금이 해제되는지조차 알지 못하며 코드의 어느 부분에서든 충분하다고 판단하여 던질 수 있습니다. 이러한 추가적인 암시 적 "안전"은 마스킹 버그 일 수 있습니다.
Matt Joiner

Matt, 우리는 그것이 잠금 해제 된 이유를 알고 있습니다. 일반적인 경우 프로그램이 스코프의 끝에 도달하면 뮤텍스가 잠금 해제되고 손으로 만든 코드로 잠금을 해제 할 필요가 없으며 유지 관리에 악몽이됩니다. 예외가 발생하면 뮤텍스가 잠금 해제되고 예외를 포착하여 오류 메시지를 읽을 수 있습니다. 오류 메시지가 충분하거나 예외를 처리하는 방법에 따라 다릅니다.
StereoMatching 2013

0

임베디드 환경에서 C ++이 받아 들여지기 어려운 주된 문제는 C ++를 올바르게 사용하는 방법을 이해하는 엔지니어가 부족하기 때문이라고 생각합니다.

예, 같은 추론이 C에도 적용될 수 있지만 다행히도 C에는 발을 쏠 수있는 함정이 많지 않습니다. 반면에 C ++에서는 C ++에서 특정 기능을 사용하지 않아야 할 때를 알아야합니다.

대체로 저는 C ++를 좋아합니다. O / S 서비스 계층, 드라이버, 관리 코드 등에 사용합니다.하지만 팀에 충분한 경험이 없다면 어려운 일이 될 것입니다.

나는 둘 다 경험했다. 나머지 팀원들이 준비가되지 않았을 때 그것은 완전히 재앙이었습니다. 반면에 좋은 경험이었습니다.


0

예! 나는이 두 언어를 모두 경험했고 내가 찾은 것은 C ++가 더 친숙한 언어라는 것입니다. 더 많은 기능으로 용이합니다. C ++는 다형성, 인터 리턴 스, 연산자 및 함수 오버로딩, C에서 실제로 지원되지 않는 사용자 정의 데이터 유형과 같은 추가 기능을 제공하므로 C 언어의 상위 집합이라고 말하는 것이 좋습니다. 수천 줄의 코드가 다음과 같이 몇 줄로 줄어 듭니다. C에서 C ++로 이동하는 주된 이유 인 객체 지향 프로그래밍의 도움.


C ++는 실제로 C의 상위 집합이 아닙니다. C ++ 컴파일러에서 컴파일하지 못하는 C 코드를 작성하는 것은 매우 쉽습니다. 반면에 Objective-C는 C의 엄격한 수퍼 세트였습니다.
ex nihilo

@exnihilo 여기서 관례 수퍼 세트는 C ++에 더 많은 기능이 제공된다는 것을 정의하는 것입니다. 또한 구문과 의미를 개선하고 오류 가능성을 줄입니다. const int a와 같이 C ++에서는 컴파일되지 않았지만 C에서는 할 수있는 코드가 있습니다. C에서 개념이 컴파일되는 동안 선언시 상수를 초기화해야하므로 C ++에서 오류가 발생합니다. 따라서 수퍼 세트는 수학 (A⊂B)처럼 어렵고 빠른 규칙이 아니라 C ++가 객체 지향 개념과 같은 추가 기능을 제공하는 근사치입니다.
kaynat liaqat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.