Program Club

typedef 포인터를 사용하는 것이 좋은 생각입니까?

proclub 2020. 11. 2. 20:06
반응형

typedef 포인터를 사용하는 것이 좋은 생각입니까?


나는 몇 가지 코드를 살펴 보았고 규칙이 다음과 같은 포인터 유형을 바꾸는 것임을 알았습니다.

SomeStruct* 

으로

typedef SomeStruct* pSomeStruct;

이것에 어떤 장점이 있습니까?


이것은 포인터 자체가 "블랙 박스", 즉 내부 표현이 코드와 관련이없는 데이터 조각으로 간주 될 때 적절할 수 있습니다.

기본적으로 코드가 포인터를 역 참조 하지 않고 API 함수 주변에 전달하면 (때로는 참조로) typedef가 *코드 s 수를 줄일 뿐만 아니라 포인터가 포인터를 가져야한다고 제안합니다. 정말 간섭하지 마십시오.

이렇게하면 나중에 필요할 때 API를 더 쉽게 변경할 수 있습니다. 예를 들어 포인터가 아닌 ID를 사용하도록 변경하면 (또는 그 반대로) 포인터가 처음에 역 참조되지 않아야했기 때문에 기존 코드가 깨지지 않습니다.


내 경험으로는 아닙니다. ' *'를 숨기면 코드를 읽기가 어렵습니다.


typedef 내에서 포인터를 사용하는 유일한 경우는 함수에 대한 포인터를 다룰 때입니다.

typedef void (*SigCatcher(int, void (*)(int)))(int);

typedef void (*SigCatcher)(int);

SigCatcher old = signal(SIGINT, SIG_IGN);

그렇지 않으면 도움이되는 것보다 더 혼란 스럽습니다.


삼진 선언은 signal()신호 캐처가 아닌 함수 에 대한 포인터에 대한 올바른 유형입니다 . 다음과 SigCatcher같이 작성 하면 더 명확하게 만들 수 있습니다 ( 의 수정 된 유형 사용 ).

 typedef SigCatcher (*SignalFunction)(int, SigCatcher);

또는 signal()함수 를 선언하려면 :

 extern SigCatcher signal(int, SigCatcher);

즉, a SignalFunction는 두 개의 인수 (an int및 a SigCatcher)를 받고 a를 반환하는 함수에 대한 포인터 SigCatcher입니다. 그리고 signal()그 자체는 두 개의 인수 (an int및 a SigCatcher) 를 취하고 SigCatcher.


이렇게하면 일부 오류를 방지 할 수 있습니다. 예를 들어 다음 코드에서 :

int* pointer1, pointer2;

pointer2는 int * 가 아니라 간단한 int 입니다. 그러나 typedef를 사용하면 이런 일이 발생하지 않습니다.

typedef int* pInt;
pInt pointer1, pointer2;

이제 둘 다 int * 입니다.


내 대답은 "아니오"입니다.

왜?

글쎄, 우선, 당신은 단순히 하나의 문자 *를 다른 하나의 문자로 교환합니다 p. 그것은 제로 이득입니다. 무의미한 추가 작업을 수행하는 것은 항상 나쁘기 때문에 이것만으로도이 작업을 수행 할 수 없습니다.

둘째, 그것은 중요한 이유입니다 *그 숨기기에 좋지 않은 의미를 전달 . 이와 같은 함수에 무언가를 전달하면

void foo(SomeType bar);

void baz() {
    SomeType myBar = getSomeType();
    foo(myBar);
}

myBar에 전달하여 의 의미 가 변경 될 것으로 기대하지 않습니다 foo(). 결국, 나는 가치로 전달하고 있으므로 권리 foo()의 사본 만 볼 myBar수 있습니까? SomeType어떤 종류의 포인터를 의미하기 위해 별칭이 지정 되지 않았습니다 !

이는 C 포인터와 C ++ 스마트 포인터 모두에 적용됩니다. 사용자에 대한 포인터라는 사실을 숨기면 완전히 불필요한 혼란이 발생합니다. 따라서 포인터에 별칭을 지정하지 마십시오.

(나는 포인터 유형을 typedef하는 습관은 프로그래머로서 얼마나 많은 별을 숨기려는 잘못된 시도 일 뿐이라고 생각합니다 . http://wiki.c2.com/?ThreeStarProgrammer .)


이것은 스타일의 문제입니다. 이러한 종류의 코드는 Windows 헤더 파일에서 자주 볼 수 있습니다. 그들은 소문자 p를 접두사로 붙이는 대신 모두 대문자 버전을 선호하는 경향이 있습니다.

개인적으로 나는 typedef의 사용을 피합니다. 사용자가 PFoo보다 Foo *를 원한다고 명시 적으로 말하는 것이 훨씬 더 명확합니다. Typedef는 요즘 STL을 읽을 수 있도록 만드는 데 가장 적합합니다. :)

typedef stl::map<stl::wstring,CAdapt<CComPtr<IFoo>> NameToFooMap;

(많은 답변과 마찬가지로) 상황에 따라 다릅니다.

C에서 이것은 객체가 포인터라고 위장하려고 할 때 매우 일반적입니다. 이것이 모든 함수가 조작하는 객체라는 것을 암시하려고합니다 (아래의 포인터라는 것을 알고 있지만 조작중인 객체를 나타냄).

MYDB   db = MYDBcreateDB("Plop://djdjdjjdjd");

MYDBDoSomthingWithDB(db,5,6,7);
CallLocalFuc(db); // if db is not a pointer things could be complicated.
MYDBdestroyDB(db);

MYDB 아래에는 아마도 일부 개체에 대한 포인터가 있습니다.

C ++에서는 더 이상 필요하지 않습니다.
주로 참조로 전달할 수 있고 메서드가 클래스 선언에 통합되기 때문입니다.

MyDB   db("Plop://djdjdjjdjd");

db.DoSomthingWithDB(5,6,7);
CallLocalFuc(db);   // This time we can call be reference.
db.destroyDB();     // Or let the destructor handle it.

Typedef는 코드를 더 읽기 쉽게 만드는 데 사용되지만 포인터를 typedef로 만들면 혼란이 커집니다. typedef 포인터를 피하는 것이 좋습니다.


관심있는 언어가 C라는 가정하에 토론이 진행되었습니다. C ++에 대한 결과는 고려되지 않았습니다.

태그없는 구조에 aa 포인터 typedef 사용

포인터로 정의 된 구조체의 크기 라는 질문 typedef for (구조) 포인터 사용에 대한 흥미로운 측면을 제기합니다 .

태그없는 콘크리트 (불투명하지 않음) 구조 유형 정의를 고려하십시오.

typedef struct { int field1; double field2; } *Information;

The details of the members are completely tangential to this discussion; all that matters is that this not an opaque type like typedef struct tag *tag; (and you can't define such opaque types via a typedef without a tag).

The question raised is 'how can you find the size of that structure'?

The short answer is 'only via a variable of the type'. There is no tag to use with sizeof(struct tag). You can't usefully write sizeof(*Information), for example, and sizeof(Information *) is the size of a pointer to the pointer type, not the size of the structure type.

In fact, if you want to allocate such a structure, you can't create one except via dynamic allocation (or surrogate techniques that mimic dynamic allocation). There is no way to create a local variable of the structure type whose pointers are called Information, nor is there a way to create a file scope (global or static) variable of the structure type, nor is there a way to embed such a structure (as opposed to a pointer to such a structure) into another structure or union type.

You can — must — write:

Information info = malloc(sizeof(*info));

Apart from the fact that the pointer is hidden in the typedef, this is good practice — if the type of info changes, the size allocation will remain accurate. But in this case, it is also the only way to get the size of the structure and to allocate the structure. And there's no other way to create an instance of the structure.

Is this harmful?

It depends on your goals.

This isn't an opaque type — the details of the structure must be defined when the pointer type is typedef'd.

It is a type that can only be used with dynamic memory allocation.

It is a type that is nameless. The pointer to the structure type has a name, but the structure type itself does not.

If you want to enforce dynamic allocation, this seems to be a way to do it.

On the whole, though, it is more likely to cause confusion and angst than enlightenment.

Summary

It is, in general, a bad idea to use typedef to define a pointer to a tagless stucture type.


If you do this, you will be unable to create STL containers of const pSomeStruct since the compiler reads:

list<const pSomeStruct> structs;

as

list<SomeStruct * const> structs;

which is not a legal STL container since the elements are not assignable.

See this question .


No.

It will make your life miserable the moment you mix it with const

typedef foo *fooptr;
const fooptr bar1;
const foo *bar2

Are bar1 and bar2 the same type?

And yeah, I am just quoting Herb Sutter's Guru. Much truth did she speak. ;)

-- Edit --

Adding link to cited article.

http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835


Win32 API does this with just about every structure (if not all)

POINT => *LPPOINT
WNDCLASSEX => *LPWNDCLASSEX
RECT => *LPRECT
PRINT_INFO_2 => *LPPRINT_INFO_2

It's nice how it is consistent, but in my opinion it doesn't add any elegance.


The purpose with typedef is to hide the implementation details, but typedef-ing the pointer property hides too much and makes the code harder to read/understand. So please do not do that.


If you want to hide implementation details (which often is a good thing to do), do not hide the pointer part. Take for instance at the prototype for the standard FILE interface:

FILE *fopen(const char *filename, const char *mode);
char *fgets(char *s, int size, FILE *stream);

here fopen returns a pointer to some structure FILE (which you do not know the implementation details for). Maybe FILE is not such a good example because in this case it could have worked with some pFILE type that hid the fact that it is a pointer.

pFILE fopen(const char *filename, const char *mode);
char *fgets(char *s, int size, pFILE stream);

However, that would only work because you never mess around with the content that is pointed to directly. The moment you typedef some pointer that you some places modify the code becomes very hard to read in my experience.


Some time ago, i'd have answered "no" to this question. Now, with the rise of smart pointers, pointers are not always defined with a star '*' anymore. So there is nothing obvious about a type being a pointer or not.

So now i'd say : it is fine to typedef pointers, as long as it is made very clear that it is a "pointer type". That means you have to use a prefix/suffix specifically for it. No, "p" is not a sufficient prefix, for instance. I'd probably go with "ptr".

참고URL : https://stackoverflow.com/questions/750178/is-it-a-good-idea-to-typedef-pointers

반응형