C가 왜 '객체 지향'언어로 간주되지 않습니까?


92

C에는 객체로 간주 될 수있는 '구조체'와 같은 자체 준 객체가있는 것으로 보입니다 (일반적으로 생각하는 높은 수준의 방식으로).

또한 C 파일 자체는 기본적으로 별도의 "모듈"입니다. 그렇다면 모듈도 '객체'와 비슷하지 않습니까? C ++과 매우 유사한 C가 왜 저수준 "절차"언어로 간주되는지 C ++가 고수준 "객체 지향"인 이유에 대해 혼란스러워합니다.

* 편집 : (설명) 왜 그리고 어디에서, '객체'가 무엇인지 아닌지에 대한 선이 그려지 는가?


40
모두-왜 다운 투표? 기본적인 질문이지만 나쁜 질문은 아닙니다.
Jon Hopkins

7
C에서 OO 원칙을 효과적으로 사용할 수 있고 (일반적으로 좋은 C 코드를 작성하는 사람들이하는 것처럼), 최신 언어와 같이 언어를 쉽게 만들 수는 없습니다.
asveikau

5
C는 단순히 데이터 추상화에 대해 다른, 더 단순하고 (정직하게는) 더 잘 정의 된 (적어도 오픈 소스 커뮤니티 중) 접근 방식을 가지고 있습니다. C ++은 추상화 강국이되어 많은 훌륭한 것들을 허용하지만, 그것들을 올바르게 사용하지 않는 방법을 이해해야하는 비용이 발생합니다. 자세한 내용은 전체 답변을 참조하십시오.
Yam Marcovic

1
곧 : Structs는 메소드를 가질 수 없습니다. (함수를 가리키는 포인터는 잘 자르지 않습니다).
SF.

1
C에서 객체 기반 프로그래밍을 수행하는 것은 다소 어려움이 있습니다. 그러나 이것이 객체 지향적 이지는 않습니다 .
Wedge

답변:


101

C에는 객체로 간주 될 수있는 'structs'와 같은 자체 준 객체가있는 것 같습니다

여러분과 함께 객체 지향 프로그래밍에 대한 Wikipedia 페이지를 읽고 전통적으로 객체 지향 스타일로 간주되는 것에 해당하는 C 스타일 구조체의 기능을 확인하십시오.

(OOP)는 "개체"를 사용하는 프로그래밍 패러다임 – 상호 작용과 함께 데이터 필드 및 방법으로 구성된 데이터 구조

C 구조체 는 상호 작용과 함께 필드 와 메서드 로 구성 됩니까? 아니.

프로그래밍 기술은 데이터 추상화, 캡슐화, 메시징, 모듈성, 다형성 및 상속과 같은 특징을 포함 할 수있다.

C 구조체는 "일등"방식으로 이러한 작업을 수행합니까? 아닙니다. 언어는 모든 단계에서 당신에게 불리하게 작용합니다.

객체 지향 접근 방식은 프로그래머가 나머지 프로그램에서 직접 액세스 할 수없는 곳에 데이터를 배치하도록 권장합니다.

C 구조체가 이것을합니까? 아니.

객체 지향 프로그램은 일반적으로 서로 다른 유형의 객체를 포함하며, 각 유형은 관리해야 할 특정 종류의 복잡한 데이터 또는 실제 객체 또는 개념에 해당합니다.

C 구조체가 이것을합니까? 예.

객체는 데이터를 적절하게 사용하도록 설계된 일련의 함수 내에 데이터를 래핑하는 것으로 생각할 수 있습니다.

아니.

각 객체는 메시지를 수신하고, 데이터를 처리하고, 다른 객체로 메시지를 보낼 수 있습니다.

구조체 자체가 메시지를주고받을 수 있습니까? 아니요. 데이터를 처리 할 수 ​​있습니까? 아니.

OOP 데이터 구조는 "자신의 연산자를 가지고 다니는"경향이 있습니다

이것이 C에서 발생합니까? 아니.

동적 디스패치 ... 캡슐화 ... 하위 유형 다형성 ... 객체 상속 ... 개방형 재귀 ... 객체 클래스 ... 클래스 인스턴스 ... 연결된 객체에 작용하는 메소드 ... 메시지 전달 .. 추상화

C 구조체의 이러한 기능이 있습니까? 아니.

정확하게 어떤 객체의 특성이 "객체 지향"이라고 생각하십니까? 내가 찾을 수 없기 때문에 어떤 구조체 정의는 사실 이외의 다른 유형을 .

물론 함수에 대한 포인터 인 필드를 가진 구조체를 만들 수 있습니다. 가상 메소드 테이블에 해당하는 함수 포인터 배열에 대한 포인터 필드를 구조체에 만들 수 있습니다. 등등. 물론 C에서 C ++를 에뮬레이트 할 수 있습니다 . 그러나 C에서 프로그래밍하는 것은 비 아이디어적인 방법입니다. C ++를 사용하는 것이 좋습니다.

또한 C 파일 자체는 기본적으로 별도의 "모듈"입니다. 그렇다면 모듈도 '객체'와 비슷하지 않습니까?

다시 말하지만, 모듈의 어떤 특성이 그것들을 객체처럼 행동하게 만드는가? 모듈이 추상화, 캡슐화, 메시징, 모듈화, 다형성 및 상속을 지원합니까?

추상화와 캡슐화는 매우 약합니다. 분명히 모듈은 모듈 식입니다. 이것이 바로 모듈이라고하는 이유입니다. 메시지? 메소드 호출은 메시지이고 모듈은 메소드를 포함 할 수 있다는 점에서만 의미가 있습니다. 다형성? 아니. 계승? 아니. 모듈은 "객체"에 대한 매우 약한 후보입니다.


15
"C ++ 에뮬레이션"(용어)이 관용적이지 않다는 것에 동의하지 않는다. 하나의 반대 예는 OS 커널이 일반적으로 파일 작업을 구현하는 방법이다. 그것들은 다소 "도메인 특정"관용구 (* nix에서 드라이버 작성으로 제한됨) 일 수 있지만, 알아볼 수 있고 어떤 목적을 위해 깨끗하게 작업을 수행합니다. OO의 개념을 충분히 수행하는 사용자 모드 라이브러리의 예도 있습니다. Gtk +와 그것이 의존하는 라이브러리를 가져 가라. 그것을 해키라고 부르면 옳을 지 모르지만 이것들은 끔찍한 일이 아닙니다
asveikau

5
@ asveikau : 연습이 특이하지 않다는 생각이 들지 않으며 (들어 보지 않더라도) "해키"는 정의상 관용적이지 않다는 것을 의미하지 않습니까?
Adam Robinson

19
@asveikau : 물론, C 프로그램을보다 스타일리쉬하게 만들기 위해 할 수있는 일이 있습니다. 그러나 당신이 말한 것처럼, 그렇게하려면 훈련이 필요합니다. 언어 기능 자체가 캡슐화, 다형성, 클래스 상속 등으로 자연스럽게 이끌지는 않습니다. 오히려 개발자는 해당 패턴을 언어에 적용 할 수 있습니다. struct가 객체와 논리적으로 동일한 것을 의미하지는 않습니다. 도대체 Lisp에서 OO 스타일로 프로그래밍 할 수는 있지만 죄수 셀이 객체라는 것을 의미하지는 않습니다.
Eric Lippert

3
@asveikau, "자신의" "아이디 엄"에 대한 당신의 (미스) 해석이 온화하다는 것을 제안 할 수 있습니까? :)
Benjol

8
@BillK : Structs는 C로 코드를 포함 할 수 없습니다. Structs 는 data 인 함수 포인터를 포함 할 수 있습니다 . 함수 포인터는 코드 가 아닙니다 . 코드 는 프로그래머가 만든 텍스트 아티팩트입니다.
Eric Lippert

46

핵심어는 "객체"가 아니라 "지향적"입니다. 객체를 사용하지만 구조체처럼 객체를 사용하는 C ++ 코드조차 객체 지향 이 아닙니다 .

C와 C ++는 모두 OOP를 수행 할 수 있지만 (C에서는 액세스 제어가 없음) C에서이를 수행하는 구문은 불편하지만 (최소한) C ++의 구문은 매우 매력적입니다. C는 절차 적 지향적 인 반면 C ++은 거의 동일한 핵심 기능에도 불구하고 객체 지향적입니다.

객체 만 사용하여 디자인을 구현하기 위해 객체를 사용하는 코드 (일반적으로 다형성을 이용하는 의미)는 객체 지향 코드입니다. 객체 지향 언어에서 상속을 사용하는 경우에도 데이터 백 이상으로 객체를 사용하는 코드는 실제로 필요한 것보다 복잡한 절차 적 코드입니다. 런타임에 데이터로 가득 찬 구조체로 변경되는 함수 포인터를 사용하는 C 코드는 일종의 다형성을 수행하며 절차 지향 언어에서도 "객체 지향"이라고 할 수 있습니다.


2
+1 C를 가리킬 때 OO가 될 수 있습니다. 편리하지는 않지만 수행 할 수 있습니다.
dietbuddha

VBA에서 객체를 만드는 것이 더 쉽지만 객체 지향적 인 것으로 간주하지는 않습니다.
JeffO

VBA "개체 기반"이라고합니다. 그것은 객체를 사용하지만 다형성으로 사용하지는 않으며, 내가 한 작은 일에서 어떤 종류의 코드 곡예를 시도하더라도 다형성을 할 수 있는지 확실하지 않습니다. 기본적으로 캡슐화가 포함 된 절차 적 언어입니다.
kylben

2
대부분의 언어는 OO, 기능적 또는 거의 모든 스타일의 언어로 작동 할 수 있습니다. 차이점은 "오리엔트"이며 이전에 그런 식으로 들어 본 적이 없습니다. 나는 이것을 3 번 투표하고 받아 들일 수 있기를 바랍니다. 정답입니다.
Bill K

1
@kylben SQL 코드를 테이블에 저장 한 다음 추출하고 실행 (테이블을 객체로 만들기)하기에는 너무 많은 노력이 필요하지 않습니다. 흥미로운 실험이 될 것입니다. 실제로 그것은 약간의 유혹입니다 ...
Bill K

19

매우 높은 수준의 보안 주체를 기반으로 :

객체는 상호 작용 방식으로 데이터와 동작을 캡슐화하여 여러 번 인스턴스화 할 수 있고 외부 인터페이스를 알고 있으면 블랙 박스로 작업 할 수 있도록 전체적으로 작동합니다.

구조체에는 데이터가 포함되어 있지만 동작이 없으므로 개체로 간주 될 수 없습니다.

모듈에는 동작과 데이터가 모두 포함되어 있지만 두 모듈이 서로 관련되어 있고 여러 번 인스턴스화 할 수없는 방식으로 캡슐화되어 있지 않습니다.

그리고 그것은 당신이 상속과 다형성에 들어가기 전에 ...


모듈의 동작 및 데이터는 어떤 관련이 없습니까? 멤버는 기본적으로 모듈 내에 존재하는 데이터의 '동작'을 수행하지 않습니까?
Dark Templar

4
문제는 캡슐화되지 않았으며 관련이 없다는 것입니다.
Eoin Carroll

실제로 객체는 주로 데이터가 아니라 행동 중심에 있습니다. 데이터는 OOP에서 2 등 시민이어야합니다. Structs는 대신 데이터 중심이며 동작이 없습니다.
Sklivvz

1
@Dark Templar-Eoin의 말 ... 관계의 본질에 있습니다. 당신이에서오고있어 어디 볼 수 있습니다 - 그것은 에뮬레이트 당신이 확실히하는 방법으로 모듈 내에서 구조체를 사용할 수있는 몇 가지 아주 아주 기본적인 OO의 요소 그러나 당신이 세트에 고집 프로그래머에 의존 할 일을해야했던 것과 많이 언어를 강요하기보다는 스스로 부과 한 규칙. 왜 귀찮게하겠습니까? 당신은 OO의 이점을 얻지 못합니다-예를 들어 상속받지 마십시오-당신은 스스로를 제한하고 있습니다.
Jon Hopkins

이것은 올바른 것으로 표시된 것보다 더 나은 대답입니다.
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

6

"structs"는 데이터입니다. "객체 방향"에 대한 일반적인 빠르고 더러운 테스트는 "코드와 데이터를 단일 단위로 캡슐화 할 수있는 구조입니까?"입니다. C는 실패하고 따라서 절차 적입니다. C ++은 그 테스트를 통과합니다.


6
해결 방법이 있으며 구조체에는 멤버 함수에 대한 정적 함수 포인터가있을 수 있습니다. 명시적인 this포인터 가 필요 하지만이 경우 데이터를 처리하기위한 데이터와 수단이 구조 내부에 캡슐화됩니다.
코더

@ Brian Knoblauch : 그러나 C 파일 자체는 데이터와 코드의 캡슐화가 아닙니까?
Dark Templar

@DarkTemplar 어떤 의미에서, 번역 단위를 만들거나 컴파일하고 런타임에 실행중인 프로세스에로드하지 않는 한 약간의 이점이 있습니다.

번역 단위? >. <
Dark Templar

@Dark 기사단 : 번역 단위가 소스 파일 플러스 아무거나 #include조건에 포함되지 그것으로 D 및 마이너스하지 제거 아무것도 ( #if, #ifdef, 등).
David Thornley

5

C ++는 C ++과 마찬가지로 Data Abstraction 을 제공 할 수 있으며 , 이는 이전에 존재했던 객체 지향 프로그래밍 패러다임의 관용구입니다.

  • C 구조체는 데이터를 가질 수 있습니다 (그리고 그 주된 목적입니다)
  • C 구조체는 함수 포인터를 데이터로 정의 할 수도 있습니다
  • C 구조체는 메서드와 마찬가지로 함수와 관련된 함수 집합을 가질 수 있으며 종종 포인터 만 암시 적으로 전달되지는 않지만 지정된 구조체를 처리하도록 설계된 각 메서드의 첫 번째 인수로 명시 적으로 지정해야합니다. C ++은 클래스 / struct 메소드 를 정의 하고 호출 할 때 자동으로이를 수행 합니다.

C ++의 OOP는 데이터를 추상화하는 수단을 확장합니다. 어떤 사람들은 그것이 해롭다 고 말하지만 다른 사람들은 올바르게 사용하면 좋은 도구라고 생각합니다.

  • C ++는 타입이 (적어도 부분적으로) 식별 될 수있는 한, 사용자가 포인터를 "클래스 / 구조의 메소드"에 전달할 필요가 없도록 하여이 포인터를 암시 적으로 만듭니다 .
  • C ++를 사용하면 특정 메소드 (클래스 함수)에 대한 액세스를 제한 할 수 있으므로보다 "방어적인 프로그래밍"또는 "멍청이 방지"가 가능합니다.
  • C ++는 도입함으로써 더 강력한 형식 안전성을 제공함으로써 추상화를 장려합니다
    1. 새로운 대신 운영자 의 malloc + 캐스트
    2. void 포인터 대신 템플릿
    3. 매크로 대신 형식화 된 값을받는 인라인 함수
    4. 구현할 필요가없는 다형성 이 내장되어 추상화 계층 , 계약전문화 를 만들 수 있습니다 .

그러나 C가 적절한 양의 추상화를 완벽하게 수행 할 수있는 방법과 C ++에 의해 생성 된 오버 헤드가 실제 문제를 해결하는 데 방해가되는 방법에 대해 설교하는 많은 C "해커"가 있습니다.

2 년이 걸리는 비효율적 인 추상화 된 프로그래밍 모델 일부 추상화가 그다지 효율적이지 않다는 것을 알았지 만 이제는 모든 코드가 주변의 모든 멋진 개체 모델에 의존하므로 앱을 다시 작성하지 않고는 수정할 수 없습니다. -리누스 토발즈

다른 사람들은 단점과 함께 두 가지 장점을 모두 받아 들여보다 균형 잡힌 방식으로 그것을 보는 경향이 있습니다.

C는 발로 쉽게 쏠 수 있도록합니다. C ++은 그것을 어렵게하지만, 그렇게하면 다리 전체가 날려 버립니다. -Bjarne Stroustrup


2

당신은 동전의 다른 쪽을보아야합니다 : C ++.

OOP에서 우리는 정지, 가속, 좌회전 또는 우회전 등의 자동차와 같은 추상 객체 (그리고 그에 따라 프로그램을 설계)를 생각합니다. 함수 묶음이있는 구조체는 단순히 개념에 맞지 않습니다.

"실제"객체를 사용하면 예를 들어 멤버를 숨겨야합니다.

아래의 주석을 읽은 후에 : (거의) 모든 것이 C로 수행 될 수있는 것이 맞습니다 (항상 그렇습니다). 언뜻보기에는 c를 c ++와 구분하는 것이 프로그램을 디자인 할 때 생각하는 방식이라고 생각했습니다.

실제로 차이를 만드는 유일한 것은 컴파일러 가 정책을 부과하는 것입니다 . 즉 순수한 가상 기능 등. 그러나이 답변은 기술적 인 문제에만 관련이 있지만 C ++은 OOP를 수행하는 대신 C ++이 이러한 작업을 수행하는 데 더 나은 구문을 제공하기 때문에 코딩하는 동안 생각하는 원래의 방식이라고 생각합니다. C에서 다소 어색한 방법


왜 "번들 함수"를 가진 구조체가 개념에 맞지 않는지 잘 모르겠습니까? 답변에 +1
Dark Templar

1
액세스 제어 (개인 / 보호 / 공용) 외에도 다른 모든 것은 구조체로 수행 할 수 있습니다.
코더

1
@DarkTemplar : 음, 당신은 할 수 있습니다 당신은 자바 프로그래밍 기능을 모방 시도 할 수 있습니다처럼 (사람들이 실제로 그 주제에 대한 전자 책을 쓴 그리고 그것은 매우 드물게이기는하지만, 현실 세계에서 할) C에서 OOP를 모방하려고합니다. 그러나 C는 그에 대한 도움을 전혀 제공하지 않으므로 언어는 객체 지향적 이지 않습니다 .

1

너 스스로 말했어 C에는 객체와 비슷한 것이 있지만 여전히 객체가 아니므로 C가 OOP 언어로 간주되지 않습니다.


1
글쎄, 나는 질문이 무엇인지 짐작한다 : 왜 물체가 무엇인지 아닌지에 대한 선이 그려지는 이유는 무엇입니까?
Dark Templar

1

객체 지향은 아키텍처 패턴 (또는 메타 패턴)과이 패턴을 사용하여 구현 또는 위임하는 데 도움이되는 기능이있는 언어를 모두 의미합니다.

"OO"디자인을 구현할 수 있습니다 (Gnome 데스크탑은 아마도 순수한 C에서 수행되는 OO의 가장 좋은 예일 것입니다).

그러나 OO 설계 용량을 구현할 수 있다고해서 언어를 OO로 만들 수는 없습니다. 순수 주의자들은 "int"와 "char"와 같은 기본 "유형"을 재정의하거나 상속 할 수 없기 때문에 Java와 C ++가 진정한 OO가 아니라고 주장하며 Java는 다중 상속을 지원하지 않습니다. 그러나 가장 널리 사용되는 OO 언어이며 작업 코드를 생성하기 위해 돈을받는 대부분의 "실제"프로그래머 패러다임을 지원하므로 OO 언어로 간주합니다.

반면에 C는 (COBOL, Pascal 및 수십 가지 다른 절차 언어와 마찬가지로) 구조 만 지원하므로 모든 데이터에서 함수를 사용할 수 있다는 점에서 다중 상속을 지원한다고 주장 할 수 있지만 대부분 버그로 간주합니다 기능보다.


0

OO의 정의를 보자.

  • 메시징
  • 캡슐화
  • 늦은 바인딩

C는이 세 가지 중 어느 것도 제공하지 않습니다. 특히 가장 중요한 Messaging을 제공하지 않습니다 .


1
나는 그것에 동의하지 않을 것 같아요. C에서 메시징을 할 수 있습니다-C의 Objective C API로 작업하고 깊이를 알 수 있습니다. 함수 포인터를 통해 늦은 바인딩을 수행 할 수는 있지만 숨길 수있는 많은 구문 설탕이 없습니다. (캡슐화는 C 실제로 쉽게 불완전 구조 형식에 대한 포인터가 완벽하게 일을하고 있어요.)
DONAL 휄로우

OO에서는 상속도 중요한 것으로 간주되며 C는 그렇게하지 않습니다. C에서 캡슐화하는 가장 가까운 것은 내부 ( static) 함수와 데이터 멤버를 가질 수있는 별도의 파일입니다 .
David Thornley

@DonalFellows, Objective-C로 전달되는 실제 메시지는 C99 매크로로 쉽게 구현할 수 있습니다. 컴파일러가 수행해야 할 유일한 것은 몇 줄의 고급 코드에서 필요한 모든 구조를 정적으로 생성한다는 것입니다. 모든 기능을 C API에서 사용할 수있는 것은 아닙니다.
qpr

0

OO에는 여러 가지 핵심 요소가 있지만 가장 큰 요소는 대부분의 코드가 개체 내부의 내용을 알지 못하고 (구현이 아닌 표면 인터페이스를 참조) 개체의 상태가 관리되는 단위라는 것입니다 (즉, 객체가 종료되면 상태도 마찬가지), 일부 코드가 객체에 대한 작업을 호출하면 해당 작업이 무엇인지 또는 무엇을 포함하는지 정확히 알지 못하는 상태에서 수행합니다 (모두 수행하는 모든 패턴을 따라야합니다. 벽에 "메시지").

C는 캡슐화를 잘 수행합니다. 구조의 정의를 보지 못하는 코드는 (합법적으로) 내부를 들여다 볼 수 없습니다. 헤더 파일에 다음과 같은 정의를 넣으면됩니다.

struct FooImpl;
typedef struct FooImpl *Foo;

물론, Foos (즉, 팩토리) 를 빌드 하고 할당 된 객체 자체 (예 : "생성자"메소드를 통해)에 작업의 일부를 위임하고 또한 방법을 가져야하는 함수가 필요합니다. ( "소멸자"방법을 통해 정리하는 동안) 객체를 다시 폐기하는 것이 세부 사항입니다.

메소드 디스패치 (즉, 메시징)는 구조의 첫 번째 요소가 실제로 함수 포인터로 가득 찬 구조에 대한 포인터이며 이러한 각 함수 포인터가 Foo첫 번째 인수로 사용해야한다는 규칙을 통해 수행 될 수 있습니다 . Dispatch는 함수를 찾아서 적절한 인자 rewrite를 사용하여 호출하는 문제가되는데, 매크로 와 약간 교활한 작업은 어렵지 않습니다 . (이 함수 테이블은 클래스가 실제로 C ++과 같은 언어로 된 것의 핵심입니다.)

또한, 바인딩을 늦게 만듭니다. 모든 디스패치 코드는 객체가 가리키는 테이블에 특정 오프셋을 호출한다는 것을 알고 있습니다. 객체의 할당 및 초기화 중에 만 설정하면됩니다. 더 빠른 런타임 다이내믹스를 구매하는 훨씬 더 복잡한 디스패치 구성표를 사용할 수는 있지만 (기본 비용) 체리는 기본 메커니즘 위에 있습니다.

그렇다고 C가 OO 언어라는 의미는 아닙니다. 핵심은 C가 컨벤션 및 디스패치 메커니즘을 직접 작성하는 모든 까다로운 작업을 수행하도록합니다 (또는 타사 라이브러리 사용). 많은 작업입니다. 그것은 또한 구문이나 의미 론적 지원을 제공하지 않기 때문에 (상속과 같은 것들로) 풀 클래스 시스템을 구현하는 것은 불필요하게 고통 스러울 것입니다. OO 모델로 잘 설명 된 복잡한 문제를 처리하는 경우 OO 언어가 솔루션 작성에 매우 유용합니다. 추가적인 복잡성을 정당화 할 수 있습니다.


0

나는 C는 객체 지향 개념을 구현하기위한 완벽하게 정상적으로 괜찮은 생각 어깨를 으쓱를 . 객체 지향으로 간주되는 언어의 공통 분모 하위 집합 사이에서 볼 수있는 대부분의 차이점은 실제로 일종의 실용적인 관점에서 볼 때 사소하고 구문 적입니다.

정보 숨기기부터 시작하겠습니다. C에서는 구조의 정의를 숨기고 불투명 포인터를 통해 구조를 정의하면됩니다. 이는 클래스를 사용할 때 데이터 필드 의 public비교와 private구별을 효과적으로 모델링합니다 . 표준 C 라이브러리는 정보 숨기기를 달성하기 위해이 기능에 크게 의존하기 때문에 쉽게 수행 할 수 있고 안티-이디 오마 틱은 거의 없습니다.

물론 불투명 유형을 사용하여 구조가 메모리에 할당되는 위치를 쉽게 제어하는 ​​기능을 잃어 버릴 수는 있지만 C와 C ++의 차이점은 주목할 만합니다. C ++은 메모리 레이아웃에 대한 제어를 유지하면서 C에 비해 객체 지향 개념을 프로그래밍하는 기능을 비교할 때 확실히 뛰어난 도구이지만 반드시 Java 또는 C #이 C보다 우수하다는 것을 의미하지는 않습니다. 메모리에서 객체가 할당되는 위치를 제어하는 ​​기능을 완전히 잃습니다.

그리고 우리는 큰 whoop 과 fopen(file, ...); fclose(file);는 반대로 구문을 사용해야합니다 file.open(...); file.close();. 누가 정말 신경 쓰나요? 아마도 IDE에서 자동 완성에 크게 의존하는 사람 일 수도 있습니다. 나는 이것이 실용적인 관점에서 매우 유용한 기능 일 수는 있지만 언어가 OOP에 적합한 지에 대한 논의가 필요한 것은 아니라는 점을 인정합니다.

우리는 효과적으로 protected필드를 구현할 능력이 없습니다 . 나는 거기에 완전히 제출할 것이다. 그러나 " 모든 OO 언어에는 서브 클래스가 일반 클라이언트가 액세스 할 수없는 기본 클래스의 멤버에 액세스 할 수있는 기능이 있어야합니다. "라는 구체적인 규칙이 없다고 생각 합니다 . 게다가 유지 보수 장애물이되는 것으로 의심되지 않는 보호 멤버의 유스 케이스는 거의 볼 수 없습니다.

물론 우리는 그 유비 초기화 조금 더 상용구 동적 파견 그들에게 함수 포인터의 테이블과 포인터 OO 다형성을 "모방"할 vtables과를 vptrs하지만, 보일러의 약간은 나에게 많은 슬픔을 발생하지 않았다.

상속은 거의 같은 방식입니다. 컴포지션을 통해 쉽게 모델링 할 수 있으며 컴파일러의 내부 작업에서 동일한 것으로 요약됩니다. 물론 우리는 다운 캐스트를 원한다면 타입 안전성을 잃어 버리고 , 당신이 전혀 다운 캐스팅 하고 싶다면 C에서 사람들이 다운 캐스팅 을 에뮬레이트하기 위해 하는 일이 유형에서 끔찍할 수 있기 때문에 C를 사용하지 말라고 말하고 싶습니다. 안전의 관점에서, 그러나 오히려 사람들은 전혀 다운 캐스트 하지 않을 것 입니다. 타입 안전성은 컴파일러가 비트와 바이트로 해석하기에 너무 많은 여지를 제공하여 컴파일 타임에 오류를 잡을 수있는 능력을 희생하면서 C에서 쉽게 놓칠 수있는 것이지만 객체 지향으로 간주되는 일부 언어는 정적으로 입력되지 않았습니다.

dunno, 괜찮아요. 물론 C를 사용하여 SOLID 원칙을 준수하는 대규모 코드베이스를 만들려고 시도하지는 않았지만 반드시 객체 지향 프론트의 단점으로 인한 것은 아닙니다. 이러한 목적으로 C를 사용하려고 시도했을 때 놓칠 수있는 많은 기능은 강력한 유형 안전, 객체가 범위를 벗어날 때 자동으로 호출되는 소멸자와 같은 OOP의 전제 조건으로 직접 간주되지 않는 언어 기능과 관련이 있습니다. 오버로드, 템플릿 / 일반 및 예외 처리. C ++에 도달하는 보조 기능이 누락되었을 때입니다.


1
생성자가 OOP의 전제 조건으로 간주되지 못한 방법을 잘 모르겠습니다. 캡슐화의 기본 본질 중 하나는 객체의 불변성을 보장하는 기능입니다. 그리고 그것은 그 불변 안에서 객체를 적절히 초기화 할 수 있어야합니다. 이를 위해서는 생성자 : 하나 이상의 함수가 필요합니다. 하나 이상의 함수가 호출 될 때까지 객체가 아직 존재한다고 말할 수 없습니다.
Nicol Bolas

우리가 불투명 한 유형으로 정보를 숨길 때, 그것들을 인스턴스화하고 복사 / 복제하고 파괴하는 유일한 방법은 불변량을 유지하는 능력이 많은 생성자와 소멸자로 기능하는 유사한 기능을 이용하는 것입니다. 그냥 직접 언어로 모델링 아니에요과의 형태를 유사 할 수 있습니다 foo_createfoo_destroyfoo_clone, 예를 들면

struct Foo이러한 경우 에 불변을 유지하기 위해 필요한 것은 외부 세계에서 데이터 멤버에 액세스하고 변형 할 수 없도록하는 것입니다. 불투명 한 유형 (외부 세계에 선언되어 있지만 정의되지 않은)은 즉시 제공합니다. 아마도 pimplC ++ 의 정보 숨기기와 비교할 때 더 강력한 형태의 정보 숨기기 입니다.

예, 사람들이 C에서 OOP를 구현하는 방법을 알고 있습니다. 감사합니다. 내 요점은 생성자가 "OOP의 전제 조건으로 직접 간주되지 않는다"는 진술에 오류가 있다는 것입니다.
Nicol Bolas 2012

lemme이 올바른지 알지만 ...이 경우 C가 소멸자와 생성자를 지원 (적절합니까?)한다고 말할 수 있습니까?

-1

나쁜 질문은 아닙니다.

c를 OO 언어로 부르려면 모든 절차 적 언어 OO도 호출해야합니다. 따라서이 용어는 의미가 없습니다. c는 OO에 대한 언어 지원이 없습니다. 구조체가 있지만 구조체가 types클래스 가 아닌 경우

실제로 c에는 대부분의 언어와 비교할 때 많은 기능이 없습니다. 그것은 속도, 단순성, 인기 및 수많은 라이브러리를 포함한 지원에 주로 사용됩니다.

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