명명되지 않은 구조체의 전달 선언
현상금 질문: 자, 이 두 가지는Foos는 같은 것이 아닙니다.좋습니다. 두 번째 양식은 도서관에서 드립니다.변경할 수 없는 상황에서 어떻게 미리 신고해야 합니까?
저는 항상 반복적인 정의가 없다면 C와 C++가 반복적인 선언을 허용한다고 생각했습니다.그러던 중 C 라이브러리를 확장하는 C++ 코드를 작성하려고 할 때 이 문제를 발견했습니다.
struct Foo;
typedef struct {} Foo;
이 경우 다음 오류가 발생합니다.
'struct Foo'에는 'struct Foo'라는 이전 선언이 있습니다.
나는 선언하고 싶어, 젠장!여기 왜 그래요?
typedefef-anonymous struct는 C++03 이전의 작업 방식이며 주로 C99 이전의 컴파일러와의 호환성을 유지하기 위한 것입니다.
지금이 2011년이고, C++과 C가 모두 변경되었다는 것을 고려할 때, 저는 왜 그러한 라이브러리의 최신 버전이 더 이상 없는지 궁금합니다!
더 이상 개발 중이 아니라면 "떠날" 수 없고, 그저 "생존"하고 변화시키는 것이 그 방법입니다.아직 배포 중인 경우, 문제를 개발 팀에 제출합니다.
해결 방법이 필요한 경우 구조가 상속될 수 있음을 고려하십시오.그래서 다음과 같이 선언문을 작성합니다.
struct MyFoo;
다음과 같이 정의합니다.
#include "old_library.h"
struct MyFoo: public Foo {};
그리고 당신의 모든 코드에서, 잊어버려요.Foo그리고 항상 사용합니다.MyFoo.
동일한 이름을 가진 두 개의 서로 다른 엔티티를 선언하는 것입니다. 번째, 첫째번,struct Foo이름이 지정된 구조입니다.Foo두 번째는 익명 구조의 별칭입니다.
대신 수행하는 경우:
struct Foo;
struct Foo {};
효과가 있어요, 왜냐하면 당신은 당신이 다음과 같은 구조를 선언하기 때문입니다.Foo두 가지 상황에서
익명 구조체는 전달할 수 없습니다.전체 정의를 포함하거나 헤더를 변경하고 구조 이름을 지정하는 두 가지 선택사항이 남아 있습니다.
유사한 상황에서, 나는 다음과 같은 것을 가진 레거시 C 헤더는 다음과 같습니다.
== old_library.h ==
typedef struct { int data; } Foo;
== /old_library.h ==
개인 메서드에 대한 매개 변수로 C++ 클래스에서 사용합니다.
class C {
void run(Foo *ds);
...
}
#을(를) 피하려면 "old_library"를 포함합니다.h"는 C.hpp에서 다음과 같은 포워드 선언을 사용합니다.
class C {
struct Foo;
void run(Foo *ds);
...
}
그리고 C.cpp에서 저는 다음과 같은 진술을 합니다.
extern "C" {
#include "old_library.h"
}
struct C::Foo : public ::Foo {};
이런 식으로 C::를 사용합니다.투명하게 Foo 대신 Foo, 그리고 My Foo는 필요하지 않습니다!
C++로 defect를 입력할 필요가 없습니다.
struct Foo; // Forward declaration
struct Foo
{
}; // Definition
만당이그그냥을것신약▁it그냥▁if▁you▁just▁to.Foo에 struct FooC에서 typeef가 필요합니다. typeef는 다양한 방법으로 수행할 수 있습니다.
struct Foo; /* Forward declaration */
struct Foo /* The name is needed here */
{
}; /* Definition */
typedef struct Foo Foo; /* typedef */
또는
struct Foo; /* Forward declaration */
typedef struct Foo /* The name is needed here */
{
} Foo; /* Definition and typedef combined */
물론 양식을 사용할 수 있습니다.struct FooC와 C++ 모두에서.
당신의 전진 선언은 다음이 있을 것이라고 선언합니다.struct라고 하는Foo.
의 두 입니다.typedef라고 하는Foo이것들은 같은 것이 아닙니다.
typedef의 정방향 선언을 위해서는 다음과 같이 typedef로 입력되는 것을 참조해야 합니다.
struct foo;
typedef foo bar;
class foo{};
익명 구조체를 정방향으로 선언하려고 하므로 원래 도면요소의 정방향 선언에서 이름을 지정할 수 없으며, 이를 정의할 때 참조할 수도 없습니다.논리적 구문은 다음과 같습니다.
struct ;
typedef bar;
class {};
그러나 이것은 분명히 불가능하기 때문에 익명 구조를 전달할 수 없습니다.
표준화하려면 9.1-2를 살펴보겠습니다.
클래스 키 식별자로만 구성된 선언. 현재 범위의 이름을 다시 선언하거나 식별자를 클래스 이름으로 전달하는 선언입니다.클래스 이름이 현재 범위에 추가됩니다.
식별자도, 전달 선언도 없습니다.
이것의 핵심: 익명 구조물이 당신에게 정말 필요한 이점을 제공하지 않는 한 그것들을 피하세요.
여기서 특정 컴파일러에 따라 달라질 수 있습니다.
MinGW 두 선언 모두 GCC 3.4.5 사용).-Wall)
struct Foo;
typedef struct {} Foo;
그리고.
struct Foo;
typedef struct Foo {} Foo;
도서관 내에 사전 신고가 이미 존재할 가능성이 있습니까?예를 들어 원형 포인터를 허용하려면:
struct Foo;
typedef struct Foo {
struct Foo *fooPtr;
} Foo;
라이브러리 헤더 내에 이미 존재하는 경우 설명하는 오류가 발생합니다.
IMHO를 , 간히변수있다니습.typedef
typedef struct Foo {} Foo;
^^^^^
손상은 없으며 C와 C++ 모두에서 여전히 호환됩니다.이제 이를 포워드 선언할 수 있습니다.
[참고: 만약 당신이 여전히 만지지 않겠다고 고집한다면,typedef그렇다면 여기 더러운 속임수가 있습니다.
struct Foo;
#define struct struct Foo
#include"Foo.h" // contains typedef struct {} Foo;
#undef struct
이것은 효과가 있을 것입니다, 오직.Foo.h의 만합니다만.struct선언.추천하지 않습니다.]
최근에 원래 포스터와 동일한 문제가 발생하여 아래와 같이 해결한 것 같습니다.
저는 다음과 같이 정의된 타사 제공 API에 대한 래퍼를 작성하고 있습니다.
Foo.h:
typedef struct _foo
{
int i;
} Foo;
Foo* MakeFoo();
int UseFoo(Foo* foo);
제 포장지에는 Foo가 회원으로 있어야 하는데, 저는 Foo를 제 포장지의 모든 소비자들에게 노출시키고 싶지 않습니다.
Uber Foo.h:
#pragma once
struct _foo; // forward declare the actual type _foo, not the typedef Foo
class UberFoo
{
public:
UberFoo();
int GetAnswer();
private:
_foo* f;
};
UberFoo.cpp:
#include "UberFoo.h"
#include "Foo.h"
UberFoo::UberFoo()
{
this->f = MakeFoo();
}
int UberFoo::GetAnswer()
{
return UseFoo(f);
}
이제 우리 클래스의 소비자들은 _foo/Foo의 실제 정의에 액세스하지 않고도 인스턴스화할 수 있습니다.이것은 _foo에 대한 포인터를 매개 변수로 전달하거나 _foo 멤버가 있을 뿐만 아니라 함수에서 반환해야 할 경우에도 작동합니다.
main.cpp:
#include <cstdio>
#include "UberFoo.h"
int main(int argc, char* argv[])
{
UberFoo u;
printf( "The Answer = %d\n", u.GetAnswer());
return 0;
}
여기서 요령은 형식 정의 이름이 아니라 실제 구조 유형을 포워드 선언하는 것이었습니다.오래된 C 코드에서 흔히 볼 수 있는 것처럼 구조가 익명이 아닌 것이 중요합니다.
typedef struct // the actual struct type underlying the typedef is anonymous here
{
int i;
} ThisWontWork;
이것이 도움이 되길 바랍니다!
이름이 없기 때문에 전달할 수 없습니다.Foo가 typedef인 이름 없는 구조입니다.
그냥 전진 선언을 피하는 게 어때요?
두 번째 정의가 헤더 파일에 있는 경우 먼저 C++ 헤더 파일에 헤더 파일을 포함할 수 있습니다.C++를 C 헤더로 생각하게 하려면 #include with를 포함합니다.extern "C" {그리고.}대부분의 경우 충분해야 합니다.
이전에 사용한 이름을 입력하려고 합니다.성명서는 완전히 유효하며 다른 이름만 사용하면 됩니다.
struct Foo; // Forward declaration of struct Foo
typedef struct {} anotherFoo; // Another structure typedefed
struct Foo {
// Variables
}; // Definition of the forward declared Foo.
typeef는 동일한 이름으로 사용할 수 없습니다.
언급URL : https://stackoverflow.com/questions/7256436/forward-declarations-of-unnamed-struct
'programing' 카테고리의 다른 글
| R 데이터 프레임의 각 행에 대해 (0) | 2023.06.13 |
|---|---|
| IntelliJ IDEA 자동 완성 소문자 SQL (0) | 2023.06.13 |
| Oracle clob 열에서 특정 문자열 검색 (0) | 2023.06.13 |
| iOS: 자동 레이아웃의 다중 줄 UI 레이블 (0) | 2023.06.13 |
| Firebase 메시징을 사용하여 우체부를 통해 푸시 전송 (0) | 2023.06.13 |