C 구조체는 함수가있는 것처럼 동작 할 수 있습니까?


13

struct구조체 와 멤버는 가질 수 있지만 함수는 할 수없는 C와 s를 사용 합니다. 이름을 지정한 문자열에 대한 구조체를 만들고 싶습니다. 문자열 의 인덱스 strstr.replace(int i, char c)어디에서 할 수 i있고 문자열 c위치를 바꾸는 문자 i입니다. 구조체가 함수를 가질 수 없거나 여전히 우리 가이 동작을 구현하고 구조체가 실제로는 새 구조체에 복사하고 업데이트하는 구조체 인 (간단한) 함수를 가질 수있는 방법이 여전히 있기 때문에 이것이 가능하지 않습니까? 할 수있는 분야?

따라서 replace접근하거나 유사 할 때 업데이트되는 새로운 구조체를 가리키는 구조체의 세 번째 멤버가 될 수 있습니다. 할 수 있었습니까? 아니면 내 의도를 방해하는 어떤 것이 내장되어 있거나 이론이나 패러다임이 있습니까?

배경은 C 코드를 작성하고 있으며 OOP 언어의 라이브러리 내장 기능이며 OOP가 문자열과 명령을 조작하는 좋은 방법이라는 것을 알고있는 기능을 재창조한다는 것입니다.


5
솔직히 이런 종류의 일을하기 위해 무료 기능을 작성하는 것이 더 나을 것이라고 생각합니다. 그러나 필요한 moxie가 있다면 cs.rit.edu/~ats/books/ooc.pdf를 읽으 십시오
Robert Harvey

5
구조체에는 함수에 대한 포인터 인 변수가 포함될 수 있습니다. 상속 기능은 없지만 동일한 서명으로 다른 함수를 가리키는 포인터로 구조체를 인스턴스화 할 수 있습니다. 함수의 첫 번째 매개 변수를 구조체의 포인터로 만들려고 할 때가 있습니다.
James McLeod

29
(STR, I, C)를 교체입니다 정말 str.replace (I, C)보다 훨씬 더 나쁜 것을? 귀하의 질문은 실제로 함수를 대체하는 것이 아니라 새로운 구문을 C로
스매시하는 것입니다

1
@RobertHarvey cs.rit.edu/~ats/books/ooc.pdf 링크에 감사드립니다 . 좋은 책 (그리고 가격은 맞습니다).
John Forkosh

3
@whatsisname : C에서는 어쨌든 구조 포인터를 함수에 전달해야하므로 어쨌든 끝납니다 str.replace(&str, i, c). C ++ this은 물론 포인터 전달을 자동화합니다 .
Jonathan Leffler

답변:


21

함수는 다음과 같아야합니다.

void
replace(struct string * s, int i, char c);

이는 첫 번째 매개 변수로 작동 할 오브젝트에 대한 포인터를 승인합니다. C ++에서는 이것을- this포인터 라고하며 명시 적으로 선언 할 필요는 없습니다. (필요한 경우 파이썬과 대조하십시오.)

함수를 호출하려면 해당 포인터를 명시 적으로 전달해야합니다. 기본적으로 o.f(…)구문 의 구문을 교환 f(&o, …)합니다. 별거 아니야

다형성 (일명 virtual함수) 을 지원하려는 경우 스토리가 더 복잡해집니다 . C로 에뮬레이트 할 수도 있습니다 ( 이 답변에 표시했습니다 .)하지만 손으로하는 것은 좋지 않습니다.

Jan Hudec 이 언급 했듯이 string_replaceC에는 이름 공간이 없으므로라는 단일 함수 만있을 수 있으므로 함수 이름 앞에 유형 이름 (예 :) 을 추가하는 습관을들이십시오 replace.


17
물론 string_replaceC에는 함수 오버로딩이없고 replace다른 유형에 대해 다른 함수를 가질 가능성이 있기 때문에 함수를 호출해야 할 것입니다 .
Jan Hudec

2
이름을 지정할 수 없습니다 string_replace. str,로 시작 mem하거나 wcs그 뒤에 소문자가 오는 이름 은 향후 확장을 위해 예약되어 있습니다.
David Conrad

43

Structs는 함수 포인터 를 가질 수 있지만 실제로는 가상 메소드에만 필요합니다. 객체 지향 C의 비가 상 메서드는 일반적으로 구조체를 첫 번째 인수로 일반 함수에 전달하여 수행됩니다. 에서 봐 G 객체 그것은 상용구를 많이 처리하기 위해 매크로를 사용 C.에 대한 OOP 프레임 워크의 좋은 예에 대한 상속 및 다형성 필요합니다.

C는 44 년 전에 만들어졌습니다. 오픈 소스에 매우 인기있는 언어입니다. 표준 C 문자열을 다루는 것이 처음이라고 생각하는 사람은 아닙니다. C 문자열 라이브러리를 검색하십시오. 바퀴를 재발 명할 필요는 없습니다.


2
다른 주목할만한 예는 CPython입니다. 이 코드는 많은 OOP 개념을 사용하지만 100 % 순수 C입니다.
Bakuriu

@Bakuriu CythonCPython을
cat

1
@cat 그는 아마도 Python C API를 의미하고 Cython은 100 % 순수하지 않습니다. docs.python.org/c-api/intro.html
JAB

5
@cat 아니요. CPython 소스를보십시오. 대부분의 작업은 실제로 OOP 패러다임을 사용하여 수행되며 대부분 파이썬 API와 일치하는 OOP API를 제공합니다.
Bakuriu

1
@Bakuriu 아, 파이썬 언어가 아닌 파이썬의 런타임, 소스 및 C API를 의미합니다. 귀하의 의견은 그다지 명확하지 않았습니다
고양이

8

함수 포인터를 사용하면 다음을 수행 할 수 있습니다.

str.replace(&str, i, c);

이것은 일반적으로 구현이 변경 될 수있는 경우에만 유용합니다.이 경우 vtable을 사용해야하므로 오버 헤드는 구조체 당 하나의 포인터입니다.

str.vtable->replace(&str, i, c);

3
나는 여전히 그것을 string_replace (& str, i, c)로 부르는 경향이 있으며, 콜 사이트가 vtable에 대해 알기보다는 string_replace 내부에서 vtable을 사용하십시오.
피트 커캄

2
@Pete str(또는 mem또는 wcs)로 시작하는 이름 과 소문자는 향후 확장을 위해 C 표준에 의해 예약되어 있으므로 호출하지 마십시오 string_replace. str_replace괜찮습니다.
David Conrad

3

예, 그들은 할 수 있습니다. C는 포인터가 메모리의 함수 블록에 대한 포인터, 함수 포인터를 허용하고 가상 함수뿐만 아니라 다형성과 같은 인터페이스를 만들 수 있다는 사실을 사용할 수 있습니다 (예쁘지 않더라도).

나는이 주제에 관한 블로그 게시물을 썼다. 최근에 C와 Go의 인터페이스와 같은 코드에 관한 내 학생 중 한 사람의 질문에 따라 여기에서 읽을 수 있습니다.

비 OO 인터페이스에 대한 블로그 게시물

그것이 당신에게 어떤 아이디어를 주는지보십시오.

코드에 무료 함수를 넣고 "this"포인터를 사용할 수도 있습니다. 즉, 다른 답변에서 설명한대로 작업 할 기존 구조체에 대한 포인터를 전달합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.