순수한 가상 함수가 0으로 초기화되는 이유는 무엇입니까?


147

우리는 항상 순수한 가상 함수를 다음과 같이 선언합니다 :

virtual void fun () = 0 ;

즉, 항상 0에 할당됩니다.

내가 이해하는 것은 이것이이 함수의 vtable 항목을 NULL로 초기화하고 여기의 다른 값으로 컴파일 타임 오류가 발생한다는 것입니다. 이 이해가 맞습니까?


12
vtable은 언어 요구 사항이 아니라 가상 메서드에 대한 구현 옵션 일뿐입니다. 컴파일러는 다른 구현으로 (즉, vtable이없고, 요소가없는) 동일한 추상화를 만들 수 있습니다.
David Rodríguez-dribeas

@hype 보충 질문을 다시하십시오-그것이 나의 대답 (그리고 다른 여러 사람들)이 말하는 것입니다.

궁금한 점, 내가 줄 경우 어떻게되는지 virtual void func() = 100;
krithikaGopalakrisnan

답변:


161

그 이유 =0는 Bjarne Stroustrup이 기능이 구현 될 당시 C ++ 커뮤니티를지나 "순수한"과 같은 다른 키워드를 얻을 수 있다고 생각하지 않았기 때문입니다. 이것은 그의 책, C ++의 디자인 및 진화 , 섹션 13.2.3에서 설명됩니다 :

궁금한 = 0 구문이 선택되었습니다. 당시에 새 키워드를받을 가능성이 없었기 때문입니다.

또한 이것은 vtable 항목을 NULL로 설정할 필요가 없으며 순수 가상 기능을 구현하는 가장 좋은 방법은 아니라고 명시 적으로 언급합니다.


4
네, 그것은 단지 구문입니다. 나는 #define PURE = 0 인 많은 프로젝트를 보았고 virtual void Foo () PURE;
i_am_jorf

79
제발 하나님은 :-) 해당 프로젝트에서 저를 멀리 유지

27
그것은 #define BEGIN {#define END} ;-)보다 훨씬 나쁘며 때로는 그것을 보았습니다.
Toon Krijthe

5
이런 종류의 멋진 것은 C ++이 그다지 세련되지 않았다고 생각합니다. 너무 많이 사용하는 것을 고려하면 이상합니다. 하루가 지날수록 언어가 좋아지기를 바랍니다.
jokoon

19
그래서, 즉, 비얀은 "설계 결함"과거 얻기 위해 "해킹을 사용"과 "마감 시한에 직면"한) (그냥) 우스운 인

78

C ++의 디자인에 대한 대부분의 "왜"질문과 마찬가지로 Bjarne Stroustrup 1 의 C ++의 디자인과 진화다음과 같습니다.

흥미로운 =0키워드는 새로운 키워드를 도입 할 수있는 확실한 대안 pure이나 새로운 키워드 abstract를받을 가능성이 없었기 때문에 선택되었습니다. 내가 제안했다면 pure, 릴리스 2.0은 추상 클래스없이 제공되었을 것입니다. 더 좋은 구문과 추상 클래스 중 하나를 선택하면 추상 클래스를 선택했습니다. 지연을 위험에 빠뜨리고 특정 싸움을 벌이는 대신 pure, 0을 사용하는 전통 C 및 C ++ 규칙을 사용하여 "없음"을 나타냅니다. =0기능 체 함수 포인터 벡터로서 구현되는 가상 함수 세트 (단순하지만, 일반적으로 적절한) 볼과 같은 기능을위한 초기화 것이 내보기 구문 맞는다. [...]

1 §13.2.3 구문


29

C ++ 표준의 섹션 9.2는 클래스 멤버에 대한 구문을 제공합니다. 다음과 같은 프로덕션이 포함됩니다.

pure-specifier:
    = 0

가치에 특별한 것은 없습니다. "= 0"은 "이 함수는 순수한 가상입니다."라는 구문입니다. 초기화 또는 널 포인터 또는 숫자 값 0과는 관련이 없지만 그와의 유사성은 니모닉 값을 가질 수 있습니다.


5
C ++ 표준을 참조하기위한 +1 최고의 답변 중 하나이며 지금까지 1 표만 받았다는 것은 놀라운 일입니다. C ++ 질문을 해결하기 위해서는 표준을 읽는 것이 첫 단계가되어야합니다.
mloskot

7
@ mloskot : OP의 질문에 대답하지 않기 때문에 상황을 회복시킬 수 있습니까?
단지 누군가

6
@ just somebody-순수한 가상 함수 선언의 구문이 무엇인지, 그리고 구문이 순수 지정자를 사용한다는 표준 인용을 포함합니다 = 0. 함수 본문이 {}로 래핑 된 이유를 묻는 것과 같습니다. C ++ 구문이 정의한 것이기 때문입니다.
mloskot

19

이 뒤에 어떤 의미가 있는지 확실하지 않습니다. 언어의 구문 일뿐입니다.


16

새로운 예약어는 식별자로 이러한 단어를 사용하는 오래된 프로그램을 깨뜨리기 때문에 C ++은 항상 새로운 키워드를 소개하지 않았습니다. 그것은 종종 오래된 코드를 가능한 한 존중하는 언어의 장점 중 하나로 여겨집니다.

= 0구문은 vtable 항목을로 설정하는 것과 유사하므로 실제로 선택되었을 수 0있지만 이는 순전히 상징입니다. 대부분의 컴파일러는 이러한 vtable 항목을 프로그램을 중단하기 전에 오류를 발생시키는 스텁에 할당합니다.


3
새 키워드 도입의 단점을 설명해 +1 그것은 이론적 근거를 이해하는 데 도움이되지만 C ++ 구문은 터무니없이 복잡해 보이며 사람들이 읽을 수있게 만들었기를 바랍니다. pure키워드는 내 책에서 훌륭했을 것입니다. 어쨌든, 근거를 이해하는 것이 좋습니다.
Keith Pinson

@KeithPinson 순수한 키워드를 원한다면 할 수 있습니다 #define pure = 0.
jdh8

@ jdh8 : 어이. 그냥 ... 어.
sbi

부자 인 Bjarne의 클래스에서 그는 "순수한"키워드를 C ++로 가져 오기를 원한다고 말했지만 C ++ 컴파일러가 출시되기 전에 매우 늦은 시간에 키워드를 가져 오려고했습니다 (IIRC 2 주 미만). 표면 상으로는 그것을 만들지 못했습니다.
ThePhD

@ThePhD : ISTR 그는 또한 D & E 어딘가에 이것을 말합니다. (나는 그것을 찾아보기에는 너무 게으르다.)
sbi

11

C ++에는 순수한 가상 함수와 일반 가상 함수 선언을 구별 할 수있는 방법이 있어야합니다. 그들은 = 0구문 을 사용하기로 결정했습니다 . 그들은 순수한 키워드를 추가함으로써 쉽게 같은 일을 할 수있었습니다. 그러나 C ++은 새로운 키워드를 추가하는 것을 매우 싫어하며 다른 메커니즘을 사용하여 기능을 도입하는 것을 선호합니다.


2
-0 : 당신이 광범위한 견적을 사용, 자신의 말을 실질적으로 아무것도 없을 때 (+1에 대한 제리 관의 답변을 참조)
단지 누군가

7

이 경우 "초기화"또는 "할당"이 없습니다. = 0구성된 단지 구문 구조에서 =0중 하나를 초기화 또는 할당에 전혀 관계가없는 토큰.

"vtable"의 실제 값과 관련이 없습니다. C ++ 언어에는 "vtable"또는 이와 유사한 개념이 없습니다. 다양한 "vtables"는 특정 구현의 세부 사항에 지나지 않습니다.


3

재미있는 구문에 대한 타당한 이유는 동일한 작업을 수행하는 다른 키워드를 도입하는 것보다 (표준 수용 측면에서) 쉽다는 것입니다.

나는 이것이 Bjarne Stroustrup의 C ++의 디자인과 진화에서 언급되었다고 생각합니다.


2

나는 이것이 C ++ 문법의 일부라고 가정합니다. 컴파일러가 주어진 특정 이진 형식에 대해 실제로 이것을 구현하는 방법에는 제한이 없다고 생각합니다. 당신은 아마 초기 C ++ 컴파일러에 적합했다고 가정합니다.


2

= 0선언 순수 가상 함수를 .

이해해야 할 것은 이것이이 함수의 vtable 항목을 NULL로 초기화하고 여기의 다른 값으로 컴파일 타임 오류가 발생한다는 것입니다

나는 그것이 사실이라고 생각하지 않습니다. 그것은 단지 특별한 문법입니다. vtable은 구현 정의되어 있습니다. 순수한 멤버에 대한 vtable 항목은 생성시 실제로 제로화되어야한다고 말합니다 (대부분의 컴파일러는 vtables를 비슷하게 처리하지만).


4
사실이 아닙니다. 순수한 가상 함수에 대한 정의 를 제공하는 데 아무런 문제가 없습니다 . 유일한 것은 = 0전체 클래스를 추상화하고 순수한 함수에 대한 가상 호출을 금지하는 것입니다. 비가 상 호출은 여전히 ​​괜찮습니다. 정의 (제공 한 경우)가 사용될 때입니다.
AnT

Godbolt 출력을 살펴보십시오. 모호함이나 추측의 여지가 없습니다. 나중에 직접 살펴 보겠습니다
Lewis Kelsey

이와 항목을 대체하는 것으로 보인다 __cxa_pure_virtual arobenko.gitbooks.io/bare_metal_cpp/content/compiler_output/... 대신 자료의 :: F ()
루이스 켈시

1

"실제 기능을 가리 키도록 vtable 항목을 초기화 할 수도 있습니다"

 virtual void fun()
 {
     //dostuff()
 }

vtable 항목을 아무데도 가리 키지 않거나 (0) 함수로 정의 할 수 있다는 것이 직관적입니다. 고유 한 값을 지정하면 함수 대신 가비지를 가리킬 수 있습니다. 그러나 이것이 "= 0"이 허용되고 "= 1"이 허용되지 않는 이유입니다. "= 0"이 왜 사용되는지에 대해 Neil Butterworth가 옳다고 생각합니다


1
심지어 비슷한 의견이 있었지만 많은 사람들이 표준과 Bjarne의 의견을 인용
했으므로
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.