문제

C ++에서는 다음 사이에 차이가 있습니까?

struct Foo { ... };

그리고

typedef struct { ... } Foo;
도움이 되었습니까?

해결책

C ++에는 미묘한 차이 만 있습니다. C의 홀드 오버이며 차이가 있습니다.

C 언어 표준 (C89 §3.1.2.3, C99 §6.2.3, 그리고 C11 §6.2.3) 다른 범주의 식별자에 대한 별도의 네임 스페이스를 포함합니다. 태그 식별자 (을 위한 struct/union/enum) 그리고 일반 식별자 (을 위한 typedef 및 기타 식별자).

방금 말한 경우 :

struct Foo { ... };
Foo x;

컴파일러 오류가 발생합니다 Foo 태그 네임 스페이스에만 정의됩니다.

당신은 그것을 다음과 같이 선언해야합니다.

struct Foo x;

당신이 a를 언급하고 싶을 때마다 Foo, 당신은 항상 그것을 a라고 불러야합니다 struct Foo. 이것은 빨리 성가 시므로 추가 할 수 있습니다. typedef:

struct Foo { ... };
typedef struct Foo Foo;

지금 struct Foo (태그 네임 스페이스에서) 그리고 단지 평범한 Foo (일반 식별자 네임 스페이스에서) 둘 다 같은 것을 참조하고 유형의 개체를 자유롭게 선언 할 수 있습니다. Foo 없이 struct 예어.


구성 :

typedef struct Foo { ... } Foo;

선언에 대한 약어입니다 typedef.


드디어,

typedef struct { ... } Foo;

익명 구조를 선언하고 a typedef 그것을 위해. 따라서이 구성을 사용하면 태그 네임 스페이스에 이름이 없으며 TypEdef 네임 스페이스의 이름 만 있습니다. 이것은 또한 선언 할 수 없다는 것을 의미합니다. 앞으로 선언하려면 태그 네임 스페이스에서 이름을 지정해야합니다..


C ++에서 모두 struct/union/enum/class 선언은 암시 적으로 행동합니다 typedef'Ed, 이름이 같은 이름의 다른 선언에 의해 숨겨져 있지 않는 한. 보다 마이클 버의 대답 자세한 내용은.

다른 팁

~ 안에 이 DDJ 기사, Dan Saks는 Structs (및 클래스)를 입력하지 않으면 버그가 들어올 수있는 작은 영역을 설명합니다.

원한다면 C ++가 모든 태그 이름에 대해 typedef를 생성한다고 상상할 수 있습니다.

typedef class string string;

불행히도 이것은 완전히 정확하지는 않습니다. 그렇게 간단했으면 좋겠지 만 그렇지 않습니다. C ++는 C와 비 호환성을 도입하지 않고 스트러크, 노조 또는 열거에 대한 이러한 typedef를 생성 할 수 없습니다.

예를 들어, C 프로그램이 함수와 이름이 지정된 상태를 모두 선언한다고 가정합니다.

int status(); struct status;

다시 말하지만, 이것은 나쁜 연습 일 수 있지만 C입니다.이 프로그램에서는 상태 자체가 기능을 나타냅니다. 구조 상태는 유형을 나타냅니다.

C ++가 태그에 대한 typedefs를 자동으로 생성 한 경우이 프로그램을 C ++로 컴파일하면 컴파일러가 생성됩니다.

typedef struct status status;

불행히도,이 유형 이름은 함수 이름과 충돌하며 프로그램은 컴파일되지 않습니다. 그렇기 때문에 C ++는 단순히 각 태그에 대해 typedef를 생성 할 수 없습니다.

C ++에서 태그는 프로그램이 태그와 동일한 이름과 동일한 범위를 가진 객체, 기능 또는 열거자를 선언 할 수 있다는 점을 제외하고는 TypEdef 이름처럼 작용합니다. 이 경우 객체, 함수 또는 열거 자 이름이 태그 이름을 숨 깁니다. 이 프로그램은 태그 이름 앞에서 키워드 클래스, struct, Union 또는 Enum (적절한)을 사용하여 태그 이름을 참조 할 수 있습니다. 이러한 키워드 중 하나로 구성된 유형 이름과 태그가 포함 된 유형 이름은 정교한 유형 사례입니다. 예를 들어, 구조체 상태 및 열거의 달은 정교한 유형의 특징입니다.

따라서, 두 가지를 포함하는 C 프로그램 :

int status(); struct status;

C ++로 컴파일하면 동일하게 동작합니다. 이름 상태만으로는 함수를 나타냅니다. 이 프로그램은 정교화 된 유형 스펙 시퍼 구조체 상태를 사용하여 유형을 참조 할 수 있습니다.

그렇다면 어떻게 버그가 프로그램에 들어갈 수 있습니까? 프로그램을 고려하십시오 목록 1. 이 프로그램은 기본 생성자가있는 클래스 FOO와 FOO 개체를 Char Const *로 변환하는 변환 연산자를 정의합니다. 표현식

p = foo();

주에서는 foo 객체를 구성하고 변환 연산자를 적용해야합니다. 후속 출력 문

cout << p << '\n';

foo 클래스를 표시해야하지만 그렇지 않습니다. 기능 foo를 표시합니다.

이 놀라운 결과는 프로그램에 나와있는 헤더 lib.h가 포함되어 있기 때문에 발생합니다. 목록 2. 이 헤더는 FOO라는 기능도 정의합니다. 함수 이름 Foo는 클래스 이름 Foo를 숨기므로 Main의 Foo에 대한 참조는 클래스가 아닌 함수를 나타냅니다. 메인

p = class foo();

프로그램 전체에서 그러한 혼란을 피하는 방법은 클래스 이름 Foo에 대한 다음 typedef를 추가하는 것입니다.

typedef class foo foo;

클래스 정의 직전 또는 직후. 이 typedef는 foo 유형 foo와 함수 이름 foo (라이브러리에서) 사이에 충돌을 일으켜 컴파일 타임 오류가 발생합니다.

물론이 Typedef를 실제로 쓰는 사람은 아무도 모릅니다. 많은 훈련이 필요합니다. 오류와 같은 오류의 발생률 이후 목록 1 아마도 꽤 작을 것입니다. 많은 사람들 이이 문제에 대해 결코 우울하지 않습니다. 그러나 소프트웨어의 오류로 인해 신체 상해가 발생할 수 있다면 오류가 아무리 가능하지 않더라도 TypEdefs를 작성해야합니다.

왜 누군가가 클래스와 같은 범위의 함수 또는 객체 이름을 가진 클래스 이름을 숨기고 싶어하는 이유를 상상할 수 없습니다. C의 숨은 규칙은 실수였으며 C ++의 클래스로 확장되어서는 안됩니다. 실제로, 당신은 실수를 바로 잡을 수 있지만, 필요하지 않은 추가 프로그래밍 훈련과 노력이 필요합니다.

더 중요한 차이점 : typedefS는 앞으로 선언 할 수 없습니다. 그래서 typedef 당신은 옵션입니다 #include 포함 된 파일 typedef, 모든 것을 의미합니다 #include당신의 .h 또한 해당 파일이 직접 필요한지 여부 등을 포함합니다. 대규모 프로젝트에서 빌드 시간에 확실히 영향을 줄 수 있습니다.

없이 typedef, 어떤 경우에는 다음과 같은 선언을 추가 할 수 있습니다. struct Foo; 당신의 꼭대기에 .h 파일 만 #include 당신의 구조물 정의 .cpp 파일.

거기 ~이다 차이이지만 미묘합니다. 이런 식으로보세요 : struct Foo 새로운 유형을 소개합니다. 두 번째는 이름없는 사람을 위해 Foo (새 유형이 아닌)라는 별칭을 만듭니다. struct 유형.

7.1.3 TypEdef 지정자

1 [...]

TypEdef 지정자로 선언 된 이름은 typedef-name이됩니다. 선언 범위 내에서 Typedef-Name은 키워드와 구문 적으로 동일하며 8 항에 설명 된 방식으로 식별자와 관련된 유형의 이름을 지정합니다. 따라서 typedef-name은 다른 유형의 동의어입니다. typedef-name 새로운 유형을 소개하지 않습니다 클래스 선언 (9.1) 또는 열거 선언이하는 방식.

8 TypEdef 선언이 이름없는 클래스 (또는 Enum)를 정의하는 경우, 해당 클래스 유형 (또는 Enum 유형)으로 선언 된 첫 번째 Typedef-Name은 연결 목적으로 만 클래스 유형 (또는 열거 유형)을 표시하는 데 사용됩니다 ( 3.5). [ 예시:

typedef struct { } *ps, S; // S is the class name for linkage purposes

따라서 typedef 언제나 다른 유형의 자리 표시 자/동의어로 사용됩니다.

TypEdef struct와 함께 전방 선언을 사용할 수 없습니다.

구조물 자체는 익명 유형이므로 전달할 실제 이름이 없습니다.

typedef struct{
    int one;
    int two;
}myStruct;

이와 같은 선언은 작동하지 않습니다.

struct myStruct; //forward declaration fails

void blah(myStruct* pStruct);

//error C2371: 'myStruct' : redefinition; different basic types

Struct는 데이터 유형을 만드는 것입니다. TypEdef는 데이터 유형의 별명을 설정하는 것입니다.

C ++의 'typedef struct'와 'struct'의 중요한 차이점은 'typedef structs'의 인라인 멤버 초기화가 작동하지 않는다는 것입니다.

// the 'x' in this struct will NOT be initialised to zero
typedef struct { int x = 0; } Foo;

// the 'x' in this struct WILL be initialised to zero
struct Foo { int x = 0; };

C ++에는 차이가 없지만 C를 믿는다.

struct Foo bar;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top