C ++이 OOP에 적합하지 않습니까? [닫은]


12

C ++이 객체 지향 프로그래밍에 적합하지 않다는 질문에 대한 답변 중 하나를 읽었습니다 (어떤 것을 기억할 수는 없습니다). 그 기능이나 그와 비슷한 것을 사용할 수 있지만 순수한 OOP 의미는 아닙니다 (실제로 그 사람의 의미를 실제로 이해하지 못했습니다).

이것에 진실이 있습니까? 그렇다면 왜?



5
OOP는 잘 정의 된 용어가 아니므로 C ++가 적합한 지 아닌지에 대한 논의는 의미가 없습니다.
zvrba

답변:


31

에서 설명한 바와 같이 그래서 * 앨런 케이 (Alan Kay)는 정말 용어가 무엇인지 * "를 객체 지향"을 의미 했습니까? Alan Kay는 메시지 전달이 OOP의 중요한 부분이라고 생각했지만 "클래스가있는 C"(나중에 C ++가 됨)에는 부족한 비트입니다. C ++은 약간의 동작을 가진 구조체이지만, Smalltalk 또는 Objective-C의 객체는 전송 된 메시지로 무엇을하는지 결정할 수 있다는 점에서 "지능적"입니다. Smalltalk-esque 객체가 구현하지 않은 메시지를 수신하면 지연 추가, 메시지를 다른 객체로 전달 또는 임의의 작업을 수행 할 수 있습니다.

C ++가 객체 지향 virtual방식으로 제공하는 것은 해당 메소드가 호출되는 방식과 관련된 메소드 및 다형성입니다. 컴파일러 class는 가상 메소드 가있는 데이터 유형 (또는 )을 볼 때 각 가상 메소드에 대한 슬롯이있는 vtable을 구성합니다. 가상 메소드를 구현하는 서브 클래스는 구현을 올바른 슬롯에 배치하므로 클라이언트 코드는 가상 테이블에서 특정 기능으로 코드를 완전히 해석하지 않고 코드를 실행할 위치를 알아야합니다. 이것이 의미하는 것은 효과적으로 ++이 C입니다 않습니다 그것은 모든 컴파일러에서 구현하고, 스몰 토크 - 억양 시스템으로 가능으로하지 않습니다 비록, 여러 파견의 형태를 갖는다.

메시지 전달을 OOP의 기본으로 생각한다면 C ++로 할 는 있지만 쉽지는 않습니다. OTOH OOP를 사용하여 데이터를 해당 데이터에 작용하는 함수와 연관시키는 것을 의미한다면 C ++은 괜찮습니다.


8
+1-항상 함수 호출이 메시지를 전달하는 합리적인 방법이라고 생각했습니다. 사실, 그것은 모든 것에 대한 높은 수준의 수정이 아니라 낮은 수준의 기초입니다. 그러나 활성 객체 패턴은 그 기초에서 구축 할 수 있음을 보여줍니다.
Steve314

6
그래서이 적용뿐만 아니라 C로 ++,하지만 등 자바, C #을, 오브젝트 파스칼에 그리고 그것은 윈도우 API 메시징 시스템은 앨런이 OOP에서 가장 중요한 것은으로 무엇을 의미하는지는 것을 것을 끝 은 델파이에 의해 처리됩니다 특별히 방법
트리니다드

C #이 실제로 동적 해상도를 지원한다는 점을 제외하면 @trinidad가 정확합니다. 메시지 전달 부족 문제를 해결하기 위해 OOP에 대한 아이디어가 시간이 지남에 따라 바뀌 었다고 말할 수 있습니다. 공급 업체가 자신의 기술이 증거에

@ steve314 그렇습니다. 실제로 ObjC가 작동하는 방식으로 메시지 전송은 함수 호출로 변환되어 메소드 함수를 찾고 호출합니다. 메시지 전달을 이해하는 것이 중요한 이중 발송입니다.

1
@Paul : Win32 API에 대해 약간의 경험이 있지만 이해가되지 않습니다. 객체의 크기가 가변적이고 객체의 크기를 결정하고 메모리를 할당 한 후 다시 호출하기 위해 루틴을 먼저 호출해야하는 API는 아름다움에 대한 테스트에 실패합니다.
David Thornley

27

이런 종류의 토론은 주석, 성서의 의미 또는 미국 헌법의 의미에 대해 토론하는 사람들, 그리고 원저자 (들)가 의미하는 것처럼 마치 우리 가 중요하지 않다고 생각 하기 때문에 저를 괴롭 힙니다 .

앨런 케이는 똑똑한 사람이었고, 좋은 아이디어를 가지고 있었는데, 다른 좋은 아이디어들과 충돌하여 스몰 토크와 다른 언어로 실현되었다는 것을 알았습니다.

그는 메시아가 아니며 OOP는 하나의 진정한 프로그래밍 패러다임이 아닙니다.

많은 사람들에게 좋은 생각입니다. C ++에는 OOP 사고 방식에서 비롯된 좋은 아이디어가 있습니까? 물론 그렇습니다.


8

캡슐화, 상속 및 다형성을 의미하도록 OOP를 정의하면 C ++ OOP를 지원합니다 .

그러나 C ++은 실제로 OOP에서 뛰어나지 는 않습니다 . 한 가지 이유는 다형성이 종종 스마트 포인터의 사용에도 불구하고 가비지 수집 언어로 작업하는 것이 더 자연스러운 힙 할당 객체에 의존하기 때문입니다.

그러나 C ++이 탁월한 곳은 일반 프로그래밍입니다. C ++를 사용하면 템플릿 기반 기능 프로그래밍 기술을 통해 고효율의 일반 코드를 쉽게 만들 수 있습니다.


4

C ++은 Simula에서 OOP 기능을 빌 렸습니다. Simula 개발자 IIRC 중 한 명 이상이 C ++이 생각했던 것이 아니라고 언급했습니다.

C ++에는 추상화를위한 훌륭한 도구가 있지만 객체 지향 언어보다 혼합 패러다임 언어입니다. 객체 지향 기능이 있지만 "엄격한 OOP"가 아닌 선택 사항이 있습니다.

C ++에서 얻을 수있는 나쁜 "opt-outs"중 하나는 메서드에 대한 늦은 바인딩보다는 초기에 사용하는 것입니다. 이것이 가능할뿐만 아니라 기본값입니다. Java에서 "final"은 관련되어 있지만 어떤면에서는 더 깔끔합니다 (사소한 성능 오버 헤드를 피하는 것이 아니라 의도를 지정 함) . 이것이 기본값 이 아닙니다 .

어떤면에서 C ++는 아직 여기에있는 초기 실험의 징후를 보여줍니다. 그럼에도 불구하고 다른 OOP 언어로는 얻을 수없는 많은 장점이 있지만 여전히 좋은 도구입니다.


2
C ++은 비 OOP를 허용하고 C ++은 OOP를 허용합니다. 일부 언어는 OO가되기 위해서는 OOP를 허용해야하므로 C ++는 OO 언어입니다.
트리니다드

1
스몰 토크 명성의 Alan Kay는 C ++이 "객체 지향"이라는 용어를 만들었을 때 생각했던 것이 아니라고 말했다. C ++은 Simula 클래스를 C에 접목시킨 "C with Classes"로 시작했으며 결코 깨끗한 휴식을 취하지 않았기 때문에 초기 실험처럼 보이는 것은 놀라운 일이 아닙니다.
David Thornley

1
@Trinidad : 모든 언어는 OOP를 허용합니다. 나는 평범한 오래된 C에서 꽤 멋진 OO 코드를 많이 보았습니다. 그렇습니다. 모든 가상 메소드 테이블을 손으로 정의하는 것은 고통 스럽지만 언어는 분명히 허용 합니다.
Jan Hudec

4

모든 것을 클래스의 일부로 강요한다고해서 반드시 훌륭한 OO 코드가 생성되는 것은 아닙니다.

열악한 절차 적 프로그래머에게 Java로 프로그래밍하도록 요청하면 어딘가에 클래스를 가져 와서 정적 메인 메소드를 제공하고 1000 줄의 코드를 붙일 것입니다. 나는 그것을 보았다는 것을 안다.

Java에는 switch 문이 있습니다. switch( type ) { case typeA: bundles_of_code; break; case typeB: bundles_of_other_code; break }C ++과 Java 코드 모두 에서 등을 보았습니다 .

C ++은 많은 OO 개념을 지원하지만 표준은 그것에 의해 정의되지 않지만 많은 목표가 무엇인지에 달려 있습니다.

C ++의 주요 "가난한"의미는 객체를 다른 객체로 변환하는 클래스의 복사 구성을 허용하는 것입니다. 이것을 비활성화 할 수는 있지만 함수에서 반환 할 수는 없습니다. 다행히도 이것은 C ++ 0x에서 해결되었습니다.


3

OOP는 모든 것이 수업 중이거나 수업 중임을 확인하는 것이 아닙니다. 비 OO 코드를 "순전히 OO"언어로 작성하는 것은 완벽하게 가능합니다. 예를 들어, "main"은 전역 함수 인 것으로 종종 지적되지만 정적 main 메소드 만 포함하는 클래스를 발명하는 것은 비 OO와 같습니다.

C ++은 다양한 것들을 혼합하여 가장 잘 작동합니다. 이것이 가장 좋은 일이 가장 잘 작동하는 방식이므로 놀라운 일이 아닙니다. 종종 OOP는 매우 유용한 도구 중 하나입니다.


2

C ++은 OOP에 사용될 수 있지만 스몰 토크처럼 '순수한'것은 아닙니다. C ++에서는 사람들이 이야기하고있는 비 OOP를 수행 할 수도 있습니다.


2

비록 감정에 동의하지 않지만 C ++의 타입 시스템이 순수한 OOP가 아니라 "모든 것이 객체"가 아니라는 것은 사실입니다. 스몰 토크 에서처럼 숫자 (특히)를 쉽게 확장 할 수는 없습니다. 예를 들어 "2 + 2"의 의미를 재정의 할 수는 없습니다 ( "2 + 2"의 의미를 재정의 할 수는 있지만).

그러나 대부분의 사람들이 무엇을 아마 평균 많은 사람들이 C에서 비 객체 지향 코드를 작성 ++하지만이 "OOP"언어를 사용하고 있기 때문에 믿고 있다는 것입니다, 그들이있는 거 객체 지향. 그건 사실이 아니야. 그러나 내 의견으로는, Smalltalk에서 끔찍한 명령 코드를 작성할 수 있으며 C ++의 괜찮은 OOP 디자인보다 우수하지는 않습니다.


1

C ++에 대한 Alan Kay의 완벽한 반대 의견은 C의 매크로 언어였습니다.

"메시지 전달"이라는 개념은 단순히 클래스의 인스턴스가 메모리에 유지되고 호출 될 수있는 메소드를 노출한다는 개념입니다. 메시지 전달은 함수에 대한 포인터를 보유하는 vtables를 사용하여 C ++에서 * 시뮬레이션됩니다.

메시지 전달이 C ++에 존재하지 않는다고 말하는 것은 정확하지 않습니다. 더 정확하게 말하면 메시지 전달은 외국어 구문을 사전 처리하지 않고 C에 직접 이식하지 않기 때문에 smalltalk 및 Java와 같은 다른 언어의 필수 요소입니다.

이것은 질문의 경험 수준을 약간 넘어서는 것으로 생각되는 매우 의미 론적 언어 설계 논쟁입니다.

C ++를 싫어하는 수천 가지 이유와 C ++을 좋아할 이유는 거의 없습니다.

완벽한 망치와 완벽한 못을 찾는 대신, 완벽한 집을 찾고 경험이 필요한 올바른 도구를 찾으십시오.

Alan Kay가 두려워하는 것은 시스템 프로그래밍에서 "순수한 OOP"가 아니라는 것이 실제로 C ++의 강점이라는 것을 기억하는 것이 중요합니다. 각자 자신에게 ...


1
오브젝티브 C는 C를 기반으로 매크로 언어로 시작했지만 객체 지향 언어입니다.
Jan Hudec

1

내 생각에 그것은 유용성 문제와 같은 정의 문제가 아닙니다.

객체는 복잡한 프로그램에 대한 읽기, 쓰기 및 추론을보다 쉽게하기위한 추상화입니다. 실용적인 프로그래머에게는 언어가 "객체 지향"에 대한 특정 공식 정의의 모든 기준을 충족시키는 지 여부 (여러 경쟁 언어가있는 것 같습니다!)가 제공하는 도구가 즉, OOP의 생산성 이점을 실제로 활용할 수 있습니다.

C ++에서 객체는 굉장히 누출되는 추상화로, 프로그래머가 객체에서 메모리가 어떻게 구성되어 있는지와 관련된 불쾌한 문제, 즉 다른 OOP 언어보다 C 언어로 코딩하는 것을 연상시키는 문제에 빠지게하는 경우가 많습니다. 예를 들어 C ++ FAQ (질문과 대답) 는 다음과 같은 비판을 제공합니다.

실무자는 C ++ 이외의 OO 시스템과 C ++을 "OO"로 간주 할 수있는 특별한 방식으로 해석되는 "캡슐화, 상속, 다형성"삼위 일체 이외의 OO 정의에 익숙해지는 것이 매우 유리합니다. 예를 들어, 경계 검사 또는 가비지 수집이없는 환경이 OO 환경이 아니라는 주장은 C ++에 익숙한 사람들에게는 터무니없는 소리입니다. 그러나 많은 관점에서 보면 이치에 맞습니다. 누구든지 객체를 덮어 쓸 수 있다면 "캡슐화"는 어디에 있습니까? 객체를 배치하면 댕글 링 참조 또는 메모리 누수가 발생할 수있는 경우 시스템은 어떻게 "객체 지향"입니까? ? 주어진 장소와 시간에 어떤 종류의 물체가 있는지 말할 수있는 능력은 어떻습니까? 소프트웨어가 객체와 함께 작동한다고 말하면 어디에 있습니까? 그리고 찾을 수 없다면 소프트웨어를 어떻게 디버깅해야합니까?

C ++는 객체 지향적이지만 불쾌하고 불완전합니다. 사용자는 데이터가 실제로 잘못된 비트가 아닌 "실제"객체처럼 동작 하도록 많은 노력을 기울여야합니다 . 즉, 수명이 다할 때까지 많은 코드가 C ++로 작성되었으며, 대부분은 클래스와 동적 디스패치 사용하므로 실제 OOP에 사용할 있는 것은 자명 한 것 입니다.


진지하게 대답해야 할 것에서 FQA를 참조하기 위해 -1. FQA는 왜곡, 반 사실 및 오해의 둥지입니다.
David Thornley

@DavidThornley이 인용문 은 왜곡, 반 진실 또는 오해인가?
Alex P

거기 어딘가에. OO 언어는 경계 검사 (때로는 C ++ 표준 컨테이너에 내장되어 있어야 함)를 가져야하며 가비지 수집 (스마트 포인터는 기본 가비지 수집 임)이 강제되고 불분명합니다. 매달린 참조가 객체 지향적이지 않은 언어에 대한 문장은 명백한 증거에 의한 증거입니다. 나는 "어떤 종류의 물체를 말할 수있는 능력"에 의아해합니다. 포인터 유형은 가상 동작이없는 객체에 대해이를 제공하고 RTTI는 가상 동작이있는 객체에 대해이를 처리합니다.
David Thornley

@DavidThornley FQA의 주장에 따르면 유용한 OO 언어 에는 이러한 질문이 있어야합니다. 이는 질문과 일치하는 것입니다 (C ++ "적합한 것입니까?"). 베어 본 정의에 대한 주장은 실제로이를 해결하지 못한다고 생각한다. "알 수있는 능력": 초기화되지 않았거나 이전에 덮어 쓴 데이터에 대한 포인터를 따라 실제로 존재하지 않는 객체에 액세스하는 일반적인 오류 동작; 프로그램은 해당 쓰레기를 기꺼이 가져다가 데이터로 해석 한 다음, 범위를 벗어난 주소에 도달하거나 대규모 오류가 발생할 때까지 다른 쓰레기 데이터에 대한 쓰레기 포인터를 따릅니다.
Alex P

그러나 적어도 인용문은 경계 검사 또는 가비지 수집이없는 언어가 OO가 아니라는 주장을 강력하게 제안했으며 원하는 경우 C ++에 해당 내용이 있다는 사실을 무시했습니다. 언어가 특정 클래스의 오류를 막는 지 여부 (어떤 이유로 든)가 OO인지 여부와 직교합니다.
David Thornley 2016 년

-1

그레이엄 리가 가장 찬성 한 이유가 여기 있습니다. 다시 말하면, C ++ 클래스는 실제로 메시지 전달을 수행하지 않는다는 의미에서 객체가 아닙니다. 이것이 사람들이 C ++ 또는 oop을 배울 때 많은 것을 여행한다고 생각합니다. 사람들은 객체 지향이 'this'라고 말한 다음 C ++이 다르게 작동한다고 들었습니다. C ++은 OOP를 다르게하지 않았다. 이런 식으로 생각하면 C ++ 클래스가 의도 한 바에 대해 결코 감사하지 않을 것입니다. 즉, 추상화와 역동적 인 행동을 통합하여 절차 적 패러다임을 개선하는 것입니다. 따라서 C ++ 클래스는 기본적으로 절차 적이며 절차 적 패러다임을 개선하거나 오히려 C 구조의 고급 버전입니다.


당신의 주장에 대한 실질적인지지 이유가 있습니까? 당신은 단언을하고 의견에 동의하지 않는 사람들은 착각해야하거나 다르게 생각하면 마음이 바뀔 것이라고 주장하는 것 같습니다.
David Thornley

그럴 수 있지. 이 기사 를 읽을 수 있습니다 . 내가 말하는 것은 C ++이 엄격한 Alan Kay 의미에서 "객체 지향 프로그래밍"이 아니라는 것입니다. 그러나 OOP를 동작이있는 데이터 구조로 정의하면 c ++를 OOP로 간주 할 수 있습니다. 내 생각에 C ++ 클래스를 더 높은 수준의 절차 적 프로그래밍 추상화로 보는 것이 더 정확합니다. C ++ 클래스는 Kay 스타일 객체보다 훨씬 효율적이지만 동시성에는 더 나쁩니다. 개인적으로 저는 C ++ 클래스가 훌륭한 디자인이라고 생각합니다.
annoying_squid

1
링크에 감사하지만 Alan Kay의 의미 만 설명합니다. 또한 Smalltalk가 일반적으로 첫 번째 OO 언어로 간주되는 것에 동의하지 않으며 Wikipedia는 Stulatrup이 클래스 C를 형성하기 위해 결합한 두 언어 중 하나 인 Simula라는 것에 동의합니다. C ++ 클래스가 객체 템플릿보다 더 높은 수준의 절차 적 프로그래밍 추상화라는 주장에 관심이 있지만 여전히 그렇게 생각하는 이유를 이해하지 못합니다.
David Thornley

우리가 그것에 동의 할 수 있다면, 객체 지향은 아마도 주관적인 용어 일 것입니다. 그러나 Kay 객체는 코드를 분리하고 메시지 전달을 통해 상호 작용하는 미니 컴퓨터와 같은 역할을한다는 점에서 동시 모듈화를 도입하는보다 자연스러운 방법이라고 생각합니다. 이 모델에서 프로그램 사이의 전체 로직을 셀과 메시지로 표현할 수있는 코드가 '사이에'있을 필요는 없다. '클래스'를 사용하려면 일반적으로 모듈식이 부족한 절차 적 접착제 코드가 필요하지만 클래스가 훨씬 효율적이라는 장점이 있습니다.
annoying_squid

-1

Steve Yegge 가 가장 잘 말했습니다 .

C ++는 지구상에서 가장 멍청한 언어로, 가장 덜 지각 적이라는 의미입니다. 자체에 대해서는 모른다.

C ++의 객체 시스템은 컴파일 타임에 매우 결선 되어 고정되어있어 메시지 전달, 내부 검사, 반영, 동적 디스패치 및 지연 바인딩과 같은 OOP의 원래 개념과는 거리가 멀다. C ++과 스몰 토크가 공통적으로 가지고있는 것은 약간의 어휘입니다.


C ++는 어떤면에서 가장 지각력이 낮은 언어입니까? 언어가 지각 적이라는 것은 무엇을 의미합니까? 리플렉션 기능이 부족하다는 것은 매우 일반적이며 C ++을 군중에서 뽑지 않습니다.
David Thornley

2
지구상에서 그가 "최고"라고 어떻게 말할 수 있습니까? 나는 그 무작위 인용이 무엇을 의미하는지 전혀 모른다.
user16764

+1이 종류의 말은 C ++ basers bashers에서 많은 단점을 얻을 것이지만, 말해야합니다-수평을 다루는 제네릭이 없기 때문에 실제로 반사하지 않고 OOP 할 수는 없습니다 ( 측면)-라이프 사이클 (활성화, 폐기), 일반 오류 처리, 일반 프록시, 일반 직렬화, 일반 작업 병렬 처리-코드를 오염시키고 SoC를 분해합니다.
vski

감사. 나는 반사가없는 언어가 OOP의 좋은 예가 아니라고 말해서 -3에 도달했다고 믿을 수 없습니다.
John Cromartie

1
@JohnCromartie, 귀하의 답변에서 그 점을 자세히 설명해 주시겠습니까?
Jeremy Heiler 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.