C ++에는 있지만 Java에는없는 언어 기능을 피해야합니까?


110

프로젝트의 환경에서 C ++을 사용하도록 제한되어 있다고 가정하십시오. C ++에는 있지만 Java에는없는 일부 언어 기능 (예 : 다중 상속, 연산자 오버로드)의 사용을 방지하는 것이 좋습니까?

이유는 다음과 같습니다.

  1. Java가 C ++보다 최신이므로 Java가 C ++의 기능을 제공하지 않으면 해당 기능이 좋지 않다는 것을 의미하므로 사용을 피해야합니다.
  2. C ++ 관련 기능 (예 : 친구 기능, 다중 상속)이있는 C ++ 코드는 C ++ 프로그래머 만 유지 보수하거나 검토 할 수 있지만 C ++ 언어 별 기능없이 Java와 같은 C ++ 만 작성하면 코드를 유지 보수하거나 검토 할 수 있습니다. C ++ 및 Java 프로그래머
  3. 언젠가 코드를 Java로 변환하라는 메시지가 표시 될 수 있습니다.
  4. C ++ 전용 기능이없는 코드는 일반적으로 유지 관리가 용이합니다.
  5. 모든 C ++ 언어 별 기능 (예 : 다중 상속)에는 Java로 구현할 대안이 있어야합니다. 그렇지 않은 경우 디자인 패턴 또는 코드 아키텍처에 문제가 있음을 의미합니다.

그게 사실입니까?


7
제안을 보면 코딩 표준을 만드는 것에 대해 이야기하고 있습니다. 표준을 만들고 따르고 있다는 사실은 실제로 유지 관리 성을 향상시키는 것입니다.
Brandin

63
Java 코드도 C ++ 언어로 제공되는 기능으로 제한되어야합니까? 예를 들어 Java volatile, 패키지 개인 클래스 멤버 액세스, 리플렉션 / Introspection, finally 블록, 확인 된 예외 등을 사용하지 않습니까? C ++과 Java는 피상적으로 비슷하지만 궁극적으로 매우 다른 언어입니다.
하이드

5
사람들이 새로운 기능을 사용하지 않으려는 경우 언어는 어떻게 진화합니까? 새로운 기능의 목적은 일반적인 문제를 해결하여 삶을 편하게 만드는 것입니다. 사용자가 새로운 기능을 사용하지 않으면 누구나이를 구현할 동기가 없습니다.
Matthew

72
Java를 원하면 Java를 사용하십시오. C ++를 사용하는 경우 C ++ 구문을 사용하여 끔찍하고 왜곡 된 Java 모방이 아닌 C ++을 사용하십시오. C ++을 사용하지만 Java 기능 세트로 제한하면 두 세계 중 최악의 상황이 발생합니다.
Jerry Coffin

11
당신은 차이를 물어 (그리고 얼마나 빨리 놀랄 것 하드 ). SomeObject a = previousObject;않는 매우 자바와 C ++에서 다른 일을. Java에서는 참조를 복사하지만 C ++에서는 객체를 복사합니다. Java에서 수정 사항 a은 이전 객체에도 영향을 미칩니다. C ++에는 두 개의 개별 객체가 있습니다.
Clockwork-Muse

답변:


307

아닙니다. 이것은 비참하고 끔찍하게 잘못 인도되었습니다.

  • Java 기능은 특히 진공 상태에서 C ++ 기능보다 나은 것은 아닙니다.
  • 프로그래머가 기능을 사용하는 방법을 모른다면 더 나은 개발자를 훈련 시키거나 고용하십시오. 개발자를 팀의 최악의 상태로 제한하는 것은 좋은 개발자를 잃는 빠르고 쉬운 방법입니다.
  • 야 그니 . 미래의 문제가 아니라 오늘 실제 문제를 해결하십시오.

6
최근에 개발자가 일반적으로 작성하지 않는 언어로 코드를 검토하는 것에 대한 질문이있었습니다. 나는 여기에 적용되는 지혜가 있다고 생각합니다. 좋은 개발자는 거의 모든 언어에서 많은 기본적인 실수를 발견 할 수 있지만, 각 언어에는 언어가 너무 많아서 언어를 사용하는 개발자가 검토 할 때 최대의 이점을 얻을 수 있습니다. C ++이 "자바 기능 만"인 경우에도 마찬가지입니다.
corsiKa

5
두 번째 포인트 외에 +1. OP는 사용할 기능을 결정하기 위해 "C ++ 모범 사례"에 대해 읽는 데 시간이 걸립니다. C ++에 대한 마지막 정보는 친구 함수다중 상속나쁜 습관 으로 간주 된다는 것 입니다. 템플릿연산자 오버로드 와 같은 것은 현명하게 사용하는 경우 IMHO 모범 사례입니다.
some_coder

4
@ some_coder : 그것은 언제, 어디서 아는 문제입니다. 정책 기반 프로그래밍을 수행 할 때 (아마도 여러 개의) 정책 클래스에서 상속하여 해당 정책 클래스가 작동하는 데 필요한 구성원으로 호스트 클래스의 구조를 확장합니다. 작동 방식입니다. 또한 operator<<( ostream &, T const & )일반적으로를 통해 구현됩니다 friend. 좋은 언어 기능과 나쁜 기능에 대한 포괄적 인 설명은 문제입니다. 그렇지 않은 경우를 제외하고는 좋은 조언입니다.
DevSolar

142

구문이 표면에서 비슷해 보인다고해서 두 언어가 호환되는 것은 아닙니다.

1, 4 및 5는 실제로 같은 질문입니다.

이제 C ++을 좋아하지는 않지만 "C ++ 관련 기능이없는 코드는 일반적으로 유지 관리가 더 쉽다"고 말하는 것은 어리석은 일입니다 .Java가 모든 것을 올바르게 얻었으며 모든 나쁜 기능을 무시하면서 모든 좋은 기능을 취했다고 생각합니까? 보편적으로 "나쁜"또는 "좋은"기능이 있다고 생각하십니까? 있다면, 왜 우리는 순전히 좋은 언어를 가지고 있지 않습니까? 그리고 아닙니다. Java는 확실히 그 언어 가 아닙니다 . Java와 C ++가 쓸모 없다는 것을 의미합니까? 당연히 아니지.

리더가 Java 대신 C #으로 포팅하기로 결정하면 어떻게 될까요? C #은 연산자 재정의를 지원할뿐만 아니라 기본값이기도합니다. 예를 들어 사람들 obj.Equals(obj2)대신에 사람들이 사용해야 하는 obj == obj2경우 사람들은 항상 실수를 저지 릅니다. 두 언어의 공통 기능 만 유지하더라도 다른 기대 , 다른 문화가 있습니다. if (myField == null)C ++에서 와 같은 작업을 수행하면 사람들은 사용자가 즉시 초보자임을 알게 될 것입니다. if (null == myField)C #에서 사용하면 사람들이 실제로 C # 네이티브가 아니라는 것을 알게 될 것입니다. C 개발자가 "flipped"변형을 사용하는 방법을 배운 이유는 더 이상 C #에 없습니다.

로직을 사용하면 프로그래머가 배우는 새로운 기능을 추가 할 때 왜 파스칼과 같은 것으로 바뀌어야합니까? 루프 가 없을 때 SQL과 같은 것을 사용하는 이유는 무엇 입니까? SQL에 루프가없고 X 가 있을 때 왜 SQL 이외의 다른 것을 사용 하는가?

C ++ 코드는 확실히 Java 프로그래머가 유지할 수 없습니다. 이 아이디어를 어디서 얻었는지 이해할 수 없습니다 .C ++을 Java에서와 정확히 동일한 기능으로 만 제한하면 정확히 무엇이 남아 있습니까? 심지어 함수 호출 조차도 메소드 호출을 얻지 못할 것 입니다. 다시 말하지만, 두 언어가 중괄호를 사용한다고해서 언어가 서로 교환 가능한 것은 아닙니다.

Java와 유사한 C ++ 코드를 변환하면 어떤 작업을 수행하더라도 오류가 발생하기 쉽습니다. 차이점이 너무 많습니다. 응용 프로그램을 다른 언어로 다시 작성해야하는 경우 모든 것을 모듈화하는 합리적인 방법을 생각하여 전체를 손상시키지 않고 부품을 교체 할 수 있습니다. 그러나 결국 YAGNI-무엇을 하든지 코드를 "Java로 변환 할 준비가되게"하려면 상당한 비용이 듭니다. 이제는 기능을 추가하거나 개선하는 데 더 나은 시간을 보낼 것입니다.

우리는 문제를 해결하기 위해 다른 도구 세트를 제공하기 때문에 다른 언어를 사용합니다. "모든 곳에서"작동하는 실행 파일이 필요한 경우 Java를 사용하십시오. "모든 곳" 을 컴파일하는 코드를 원한다면 C ++이 잘 작동합니다. 이해하고 파싱하기 쉬운 코드를 원한다면 LISP와 함께 가십시오. 그러나 한 가지를 말해 줄 수 있습니다. 마치 한 언어로 코드를 작성하는 것처럼 다른 언어로 코드를 작성하는 것은 항상 실수이며 고통을 겪게됩니다. 당신이 실제로 C ++ 사용자를 고용 할 때, 그는 "Java-ish compatible"코드를 보게 될 것입니다. 그리고 ... 자바 사람도 똑같이 할 것입니다. C ++과 Java를 모두 "알고", 나는 지옥처럼 뛸 것이다. :)

나는 실제로 당신처럼 생각하는 Pascal 개발자가 작성한 C 코드를 작성해야했습니다. 그는 #defines를 사용 하여 C를 재정 의하여 파스칼처럼 보이게하고 "BEGIN translates to {"와 같은 것들을 완성했습니다. 결과는 다소 예측 가능했다. C도 파스칼 개발자도 이해할 수없는 코드와 C 위에 파스칼이 유출 된 결과 인 버그로 가득 차있다. 파스칼과 C는 오늘날의 관점 과 거의 동일하다 . C <->로 이동하더라도 C ++은 훨씬 더 큰 차이이며 여전히 C ++ <-> Java와 같은 땅콩입니다.


9
"이해하고 파싱하기 쉬운 코드를 원한다면 LISP와 함께 가십시오." 나는 그것에 동의하지 않을 것입니다. 리스프는 파싱하기는 쉽지만 정확하게 파서에 대한 지식과 효과적으로 구축하는 원리가 아직 초기 단계에 있었기 때문에 만들어 졌기 때문에 아주 터무니없이 간단하게 말을했기 때문에 만들어졌습니다. 현대 언어의 구문 상 이점을 많이 얻지 못할 수도 있습니다. 따라서 파싱하기는 쉽지만 전혀 이해 하기 쉽지 않습니다 . 사람들이 "불필요한 괄호를 잃어 버렸다"고 부르는 이유가 있습니다.
메이슨 휠러

9
@MasonWheeler 그것은 맛의 문제입니다-C 프로그래머들은 그것을 LISPers가 아니라라고 부릅니다 : P. 괄호를 세십시오-일반적인 C ++ 프로그램만큼이나 많습니다. 실제 차이점은 그들의 위치 ( myFunc()vs (myFunc))이며, 그 이유는 매우 좋습니다. LISP 기반 언어는 여전히 수학 / 물리학 자들에게 여전히 인기가 있습니다. 가장 중요한 것은 LISPy 언어가 현대 C 스타일 프로그래머 에게는 익숙하지 않다는 것입니다. 그러나 그것을 무시할 이유는 거의 없습니다. Scheme, Clojure 및 ML 기반 언어 (OCaml, F # ...)는 실제로 LISPy입니다.
Luaan

4
@Luaan LISP가 물리학에서 대중적이지 않다는 것을 확실히 말할 수 있습니다. 이 분야에서 두 가지 주요 언어는 FORTRAN과 C ++입니다. FORTRAN은 많은 오래된 코드가 작성 되었기 때문에 '인기있는'것이지만 거의 모든 새로운 프로그램이 C ++로 작성되었습니다. 리서치 물리학 자로서 LISP 프로그램에 대해 한 번도들은 적이 없습니다. 그것들이 존재하지 않는다고 말할 수는 없지만, 언어는 확실히 인기 가 없습니다 .
James Matta

4
@Luaan 더 많은 소프트웨어 개발자가 필요하거나 필요하지 않을 수 있습니다. 더 많은 CS 졸업생이 필요하지 않습니다. "우리는 더 많은 구조 엔지니어가 필요하므로 더 많은 이론 물리학 졸업자가 필요합니다."라고 말하는 것과 같습니다.
Miles Rout

4
@ user1717828 훌륭한 C / C ++를 컴파일하지만 의도 한대로 수행하지 않는if (myField == null) as와 같은 mistyping의 유쾌한 효과를 피하는 것입니다. 반면 상수를 할당 할 수 없으므로 오류가 발생합니다. if (myField = null)if (null = myField)
Wlerin

94

나는 당신의 질문에 순서대로 대답 할 것입니다.

  1. Java가 C ++에있는 기능을 제공하지 않으면 기능이 좋지 않다는 것을 의미하므로 사용하지 않아야합니다.

예, Java에없는 기능은 하드 드라이브의 혐오입니다. 코드베이스에서 구워야합니다. 순종하지 않는 사람들은 멸망 당할 것이며 그들의 영혼은 RAID 신들을 대치하는 데 사용되었습니다.

  1. C ++ 관련 기능 (예 : 친구 기능, 다중 상속)이있는 C ++ 코드는 C ++ 프로그래머 만 유지 보수하거나 검토 할 수 있지만 C ++ 언어 별 기능없이 Java와 같은 C ++ 만 작성하면 코드를 유지 보수하거나 검토 할 수 있습니다. C ++ 및 Java 프로그래머

확실하지 않은 경우 가장 능력이 적은 팀원을위한 코드를 작성하십시오. 코드는 작성되는 것보다 훨씬 자주 읽 히며, 작성할 수있는만큼 영리한 코드는 읽기에 너무 영리합니다. 프론트 데스크 직원이 이해할 수없는 코드 검토는 거부해야합니다. 주말 동안 Visual Basic 2.0으로 프로그래밍하는 방법을 가르치고 사용하는 언어에 상관없이 코딩 스타일을 에뮬레이션하십시오.

  1. 언젠가 코드를 Java로 변환하라는 메시지가 표시 될 수 있습니다.

참된! 그러나 왜 Java를 멈추어야합니까? 코드를 하루에 기본, 어셈블러 및 / 또는 펄로 변환하라는 메시지가 표시 될 수 있습니다. 모든 언어에 perl 인터프리터가 있으므로 프로그램을 긴 perl 문자열로 작성하고 선택한 언어로 인수를 마샬링하십시오.

이제 언어를 변경해야 할 때 펄 문자열을 감싸는 코드를 다시 작성하십시오.

  1. C ++ 전용 기능이없는 코드는 일반적으로 유지 관리가 용이합니다.

더 적은 기능을 사용하는 코드는 유지 관리하기 쉽다는 것이 사실입니다. 그리고 모든 언어가 튜링 머신과 동일하고 튜링 머신은 프로그래밍 언어 중 가장 적은 기능을 가지고 있으므로 위의 펄 통역사가 실제로 튜링 머신 (테이프 및 모두)을 실행하여 문제를 해결하십시오.

  1. 모든 C ++ 언어 별 기능 (예 : 다중 상속)에는 Java로 구현할 대안이 있어야합니다. 그렇지 않은 경우 디자인 패턴 또는 코드 아키텍처에 문제가 있음을 의미합니다.

C ++ 언어 별 기능은 실제로 귀중한 용도로 사용됩니다. 그들이 자바가 아니기 때문에, 그들은 혐오이며, 그것을 사용하는 사람들은 이단이라는 브랜드가 될 수 있습니다. C ++에 이러한 언어 기능이없는 경우 희생해야 할 언어 기능을 찾을 수 없습니다. C ++ 언어 기능은 문제를 해결합니다!


C ++과 Java에는 다른 기능 세트가 있습니다. C ++과 Java의 교차점에서 프로그래밍하면 언어 의 장점을 대부분 버린 코드가 생성 됩니다.

Java는 C ++ 기능의 남용에 대한 반응으로 부분적으로 개발되었습니다. 그렇다고 반응이 정당화되었다는 것을 의미하지는 않으며, 특히 특징이 성숙 된 후 수년이 지난 후에.

연산자 오버로드로 끔찍한 일을 할 수 있습니다. 그러나 모든 코드가 언어로 작성되는 것을 막지 않는 한 어떤 언어도 언어로 끔찍한 코드가 작성되는 것을 막을 수 없습니다.

또한 연산자 오버로드로 매우 우아한 작업을 수행 할 수도 있습니다. 복소수 또는 행렬처럼 작동하는 복소수 또는 행렬 클래스와 같은 간단한 것.

Java에서 사용할 수없는 C ++ 기능 사용에 대한주의 사항은주의해서 봐야합니다. 현재 기술 수준의 현재 개발자 세트가 기능을 이해하지 못한다고해서 절대 사용해서는 안된다는 의미는 아닙니다. 동시에 기능을 사용할 수 있다고해서 꼭해야하는 것은 아닙니다. 그러나 Java가 많은 상점에서는 Java가 아닌 기능에 비해 저항이 강할 수 있습니다.

언어 간 코드 변환은 구조적으로 유사하더라도 다시 작성하는 것이 가장 좋습니다. 그러한 재 작성없이 그렇게하려는 시도는 비참하게 실패 할 것입니다.

많은 C ++ 고유의 기능은 유지 관리를위한 놀라운 기능입니다. 유형 삭제 (예 std::function:)를 사용하면 계층 구조를 분리하여 종속성을 줄일 수 있습니다. 스마트 포인터 및 결정적 수명 및 RAII는 런타임 놀라움을 줄이고 리소스 상용구를 방해하지 않습니다. 강력한 정적 유형 검사는 코드가 작동하지 않고 컴파일되지 않음을 의미합니다. 믹스 인은 코드 중복을 줄입니다. ADL을 사용하면 유형 계층간에 인터페이스를 독립적으로 확장 할 수 있습니다. Lambda를 사용하면 코드가 사용되는 곳 옆에 코드를 작성할 수 있습니다. 전달 및 이동은 사본을 줄이고 기능적 스타일 (부작용이없는) 프로그래밍을 효율적으로 만듭니다. 연산자 오버로딩은 라인 노이즈를 줄이고 코드를 모델링하는 수학처럼 보이게합니다.

튜링 타르 구덩이를 조심하십시오. 당신은 (테이프와 원시 튜링 기계 포함) 언어로 모든 것을 구현할 수 있지만, 그건 당신이 의미하지 않는다 해야한다 . C ++에서 Java-esque 구문을 사용하여 C ++ 기능을 에뮬레이트하는 것은 끔찍한 생각입니다. 아무도 읽거나 이해할 수없는 유지 보수 할 수없는 코드가됩니다.

Java 디자인에서 영감얻어 C ++로 이식 할 수 있습니다 . 나는 구문을 좋아하기 때문에 파이썬 언어 기능을 가져 와서 C ++로 구현하는 것을 좋아합니다. 그러나 이것이 클래스 메소드를 명시 적 자체를 취하는 정적 메소드로 작성한 다음 비 정적 메소드 호출을 전달하는 랩퍼를 작성한다는 의미는 아닙니다.

현대의 C ++는 Java가 에뮬레이트하고 거부 한 언어와 다를 수 있습니다. 한 언어의 기능에 얽매이지 마십시오. "하나의 진정한 언어"는 없습니다. 새로운 언어와 그 특징에 대해 배우고 그 특징을 흡수하십시오.


1
-1, 긴 바람과 불분명.
djechlin

4
-1 논증, 밀짚 맨 논쟁
user949300

28
+1, 질문의 적절한 해체와 나는 웃었다 :)
cat

11
+1. 재밌지 만 요점을 유지합니다. 실제로 읽는 사람들에게 매우 명확합니다.
Luis Masuelli

14
"C ++과 Java의 교차점에서 프로그래밍하면 두 언어의 장점을 대부분 버린 코드가 만들어집니다." 정곡을 찌르다! +1
Ajedi32

56

나는 당신의 이유에 대답 할 것입니다 :

  1. 나는 당신이 그 결론에 어떻게 도달했는지 이해할 수 없습니다. 언어마다 기능이 다릅니다. 범위, 언어 구조, 때로는 제작자의 선호도 및 더 많은 이유에 따라 다릅니다. 언어의 일부 기능은 나쁠 수 있지만 일반화는 잘못된 IMHO입니다.
  2. Java처럼 C ++를 작성하면 코드가 더 나빠질 수 있습니다. 예를 들어 요즘 C ++ 11에서는 new / delete를 사용하지 않지만 공유 포인터를 사용하십시오. 귀하의 시나리오에서는 새 / 삭제에만 의존합니다. 프로그래머가 Java 만 이해하는 경우이를 훈련 시키거나 더 나은 것을 고용하십시오.
  3. 그럴 가능성이 있습니까? 왜 처음에 Java로 작성하지 않습니까? 새로운 언어로 프로그램을 처음부터 다시 작성하는 것은 일반적으로 좋지 않은 생각 이며 그러한 위험에 대해서는 정말 좋은 근거가 필요합니다.
  4. 이것은 단지 가정 일뿐입니다.
  5. IMHO는 시나리오 또는 유스 케이스에 크게 의존합니다.

27
그리고 Java 프로그래머도 사용하지 않을 것 delete입니다.
Paŭlo Ebermann 2016

8
Java 프로그래머가 모르는 메모리 누수 문제를 해결해야했습니다 delete. 내가 기억하는 것 중 적어도 하나의 경우 동적 할당 ( new)도 필요하지 않았습니다.
Ethan Kaminski

16
@EthanKaminski 그래, 이것이 C ++ 초보자, 특히 Java 배경 또는 그와 유사한 사람들을 쉽게 찾을 수있는 방법이다. 모든 것을 위해 새로운 것을 사용하지 마십시오.
Luaan

1
@ PaŭloEbermann 그렇습니다.
Simon

1
"귀하의 시나리오에서 나는 새로운 / 삭제에만 의존 할 것이다"-웃기는, "Java (like) 기능 만"C ++ 관용구가 독점적으로 사용될 것이라고 생각했을 것이다 make_shared.
Kyle Strand

26

Java에는 빠르고 안정적인 내장 가비지 수집기, 단일 루트 개체 계층 구조 및 강력한 내부 검사와 같은 C ++ 기능이 없습니다.

Java의 다른 기능은 Java 독점 기능과 함께 작동하도록 설계되었으며, 새로운 기능이 부족하기 때문에 Java에서 C ++ 기능을 많이 생략 할 수 있습니다. 예를 들어, Java에는 결정 론적 소멸자를 가진 스택 할당 객체가 없지만 마침내 이러한 부족을 보완하기 위해 블록 (및 Java 7 이후 리소스 사용 시도)과 가비지 수집기가 있습니다.

C ++에는 마침내 블록이나 가비지 수집이 없습니다. 소멸자가 Java에 없기 때문에 소멸자를 사용하지 않으면 (파이널 라이저를 계산하지 않음) 정리를 그룹화 할 수 없다는 점을 제외하고 C 레벨의 자원 관리 (예 : 모든 수동)에 있습니다. Java에는 goto가 없으므로 정리 블록으로 이동하십시오. 실제로 유지 관리 성이 향상되었다고 생각하십니까?

Java는 모든 클래스가 궁극적으로 Object에서 파생되는 중요한 객체 계층 구조를 가지고 있으며 소수의 기본 유형도 이러한 클래스에 자동 상자에 넣을 수 있습니다. 이를 통해 객체의 컨테이너를 한 번 작성하고 객체에 대한 포인터를 유지할 수 있습니다. Java 5에는 이러한 컨테이너가 필요한 캐스트를 제거하지만 여전히 거의 동일한 코드로 컴파일되는 제네릭이 도입되었습니다.

C ++에는 이러한 계층 구조가 없습니다. 여러 유형에 대해 작동하는 컨테이너 작성을 용이하게하기 위해 다른 유형에 필요한대로 컴파일러가 인스턴스화하는 청사진 인 템플리트를 사용합니다. 템플릿 (및 매크로)의 사용을 금지하고 다른 유형에 대해 동일한 컨테이너 코드를 반복해서 작성하거나 void 포인터를 사용하는 C 경로를 사용합니까? (잠깐, Java에는 void 포인터가 없습니다!) 이것이 유지 관리 성을 향상시킬 것입니까?

괜찮은 언어에는 함께 작동하도록 설계된 다양한 기능이 있습니다. 언어 B에 언어가 없기 때문에 언어 A의 기능을 금지함으로써 언어 B를 일관성있게 만드는 B의 기능을 동시에 추가하지 않기 때문에 언어 A를 방해하고 있습니다.

C ++의 허용 된 기능을 제한해서는 안된다는 것은 아닙니다. C ++는 프로그래머가 안전하고 사용하기 쉬우면서 원하는 것을 수행 할 수 있도록 강조하는 역사적으로 성장한 크고 언어이며, 모든 프로그램의 유연성이 모든 프로그램이 우수한 프로그램을 작성하는 데 필요한 것은 아닙니다. 일부 기능의 사용을 제한하는 많은 코딩 표준이 있습니다. 예를 들어 Google 가이드 라인은 대부분 여러 상속, 복잡한 템플릿 및 예외를 금지합니다 (마지막은 역사적 이유로 인한 것임). 그러나 "자바에는 없기 때문에"기능이 금지되어 있지 않습니다. 기능은 C ++ 프레임 워크 내에서만 고려됩니다.


27
노련한 C ++ 재향 군인은 일반적으로 Google 코딩 가이드 라인을 거부합니다. 최신 C ++은 이러한 기능을 사용 하기 때문에 훨씬 더 정확 합니다. 예, 훨씬 더 다릅니다.
Jan Hudec

17
C ++에는 finally 블록이 없지만 RAII가 있으므로 대부분의 경우 훨씬 좋습니다. 그리고 다시 다릅니다.
Jan Hudec

7
Java Objectvoid*여전히 대부분의 용도에 사용됩니다.
Quentin

1
기능 선택 외에도 스타일과 관용구가 있습니다. 프로그램은 작성된 언어에 대한 일반적인 관용구를 사용하면 일반적으로 읽고 유지 관리하기가 더 쉽습니다. Java와 같은 기능 만 사용하여 C ++ 프로그램의 일부를 작성할 수 있더라도 결과는 이상하고 질식 된 C ++입니다.
Patricia Shanahan

2
나는 올바른 길을 가고 있다는 것 ( "하지 마라")에 대한이 답변을지지 할 것이지만, Java가 어떻게 든 C ++보다 "더 발전된"기본 전제를 ​​견딜 수는 없다. C ++은하지 않습니다 필요 미안 나는 때문에, 문장을 완성하는 방법을 모른다 ... 가비지 컬렉터 또는 단일 루트 객체 계층 구조, 자바는 필요하지 않습니다 같은 방법으로 ... ERR를 그리워 자바 결정 소멸자를하고, finally그것들을 대체하지 않습니다. 두 언어는 근본적으로 다릅니다.
DevSolar

25

전적으로 합리적인 결론에 도달 한 숫자가 이미있을 때 다른 답변을 게시해야하는지에 대해 토론했습니다. 아이디어는 기본적으로 재난이 기다리고 있다는 것입니다. 그러나 그들은 그 결론 뒤에 어떤 관련성이 높은 이유 를 지적하지 못했다고 생각 합니다.

Java와 C ++의 차이점 은 초점을 맞춘 세부 사항보다 훨씬 더 깊게 실행 됩니다.

예를 들어 C ++에서 다중 상속 금지에 대해 이야기합니다. 먼저, 이것이 요점을 간단히 놓치고 있음을 지적하겠습니다. Java는 "인터페이스"를 "클래스"와 분리 된 것으로 정의합니다. 하나의 클래스는 하나의 다른 클래스에서만 상속하지만 임의의 수의 인터페이스를 구현할 수 있습니다.

C ++은 두 가지 개념을 그렇게 구분하지 않습니다. 자바의 인터페이스를 구현에 제공 ++ 가장 가까운 아날로그 C가 되어 다른 클래스에서 상속. 따라서, 당신은 아마, 두 가지 모두에서 합리적으로 잘 정렬 유지 해야합니다 자바 즉, 기본적으로 (클래스에 비해 인터페이스를 제한 C ++의 다중 상속을 사용하지만 거의 같은 방법으로 그 기본 클래스의 일부를 제한 할 함수 서명을 지정하지만 적어도 대부분 구현은 지정하지 않습니다.

그래도 둘 사이의 실제 차이점을 거의 긁지 않습니다. 실제로 Java 코드가 인터페이스와 해당 인터페이스를 구현하는 클래스를 정의 할 가능성이있는 경우 C ++ 코드는 인터페이스를 구현하기 위해 특별히 정의 된 것뿐만 아니라 요구 사항을 충족하는 모든 클래스에서 작동하는 일부 템플리트를 정의 할 가능성이 훨씬 높습니다 (지정합니다).

솔직히 "C ++ 구문을 사용하는 Java"인 코드를 원한다면 거의 확실하게 후자와 비슷한 것을 금지해야 할 것입니다. Java 제네릭이 지원하는 "T의 컨테이너"수준으로 템플릿 사용을 제한해야합니다. 불행히도 그렇게하면 C ++ 코드가 생성되어 아무도 현재의 상태로 유지할 수 없으며 다른 프로그래밍 언어로 번역 할 수있는 장기적인 가능성은 말할 것도 없습니다.

나중에 다른 언어로 변환 할 수있는 코드를 실제로 원한다면 가능한 한 깨끗하고 읽기 쉬운 코드를 만들기 위해 노력하십시오. 의사 코드를 작성하고 여전히 실행하는 것이 이상적입니다. 잘 작성된 최신 C ++은 제안한 하위 집합보다 훨씬 더 이상적인 방식으로 접근합니다. 작성 방법에 관계없이 Java로 번역하는 경우 개별 명령문의 구문뿐만 아니라 실제로 코드를 변환해야합니다.


많은 C ++ 기능은 Java 개념에 잘 어울리는 방식과 그렇지 않은 방식으로 사용될 수 있습니다. 프로그램의 일부 부분은 언어 기능의 겹치는 부분 집합을 벗어난 무언가를 요구할 것이며 "C ++ 구문을 사용하는 Java"와 같은 부분을 작성하려고 시도하면 끔찍한 혼란이 생길 ​​것입니다. 다른 한편으로, 코드의 다른 많은 부분은 공유 서브셋 외부에 무언가가 필요할 수 있으며, 코드 외부로 갈만한 강력한 이유가없는 코드 부분에 대해 공유 내에 머 무르려고 시도하면 도움 될 수 있습니다.
supercat

아마도 "필요할 수도있다"라고 말한 곳은 "필요하지 않을 수도있다"라는 뜻입니까? 그렇게 가정하면 동의하는 경향이 있습니다.
Jerry Coffin

예. Java를 지원하지만 C ++는 지원하지 않는 플랫폼을 지원해야하는 경우, 코드의 일부는 거의 처음부터 다시 작성해야하며, 일부는 Java 친화적 인 기술을 사용하여 작성되었는지 여부는 중요하지 않습니다. 어쨌든 다시 작성됩니다. 그러나 전체 재 작성없이 마이그레이션 할 수있는 방식으로 다른 부분을 작성할 수 있으며 경우에 따라 추가 비용이 최소화 될 수 있습니다.
supercat

4
@ supercat : OTOH, Java를 지원하지만 C ++은 지원하지 않는 플랫폼이 많기 때문에 문제를 찾는 솔루션이 거의 전부입니다.
Jerry Coffin

한편, Java 애플릿에 대한 브라우저 지원은 C ++ 애플릿보다 낫습니다. 그러나 Java와 무관 한 JavsScript에 대한 브라우저 지원은 기본적으로 두 가지 모두를 대체 할 정도로 향상되었습니다.
supercat

11

언어 X로 코드를 작성하려면 언어를 올바르게 배우고 문제 해결에 도움이되는 모든 기능을 사용하는 데 시간을 투자하십시오. 일본어에서 영어로 또는 Java에서 C ++로, 한 언어에서 다른 언어로 "단어 단어"번역을 시도 할 때 나쁜 일이 발생합니다. 문제를 잘 이해하고 사용하는 언어에 가장 자연스러운 방식으로 솔루션을 표현하는 것이 훨씬 좋습니다.

몇 년 전 저는 들여 쓰기가없는 C 프로그램을 보았습니다. 코드의 저자는 C를 사용하는 Fortran 프로그래머 였기 때문에 모든 열은 7 열에서 시작했습니다. 다른 Fortran 프로그래머는 포인터라고하는 이러한 새로운 것들에 대해 긴장했습니다. 나는 포인터에 대한 포인터를 언급 할 마음이 없었습니다. 그들이 그 자리에서 기절했을 것이라고 생각합니다.

미래에이 코드를 유지할 누군가를 고용한다고 상상해보십시오. 좋은 C ++ 코드 인 경우 유능한 C ++ 개발자를 고용 할 수 있으며 길을 찾을 수 있어야합니다. "C ++의 Java"인 경우 C ++ 또는 Java 개발자 모두 코드를 쉽게 이해할 수 없습니다.


7

모든 이유가 반증 될 수 있습니다.

Java가 C ++에있는 기능을 제공하지 않으면 기능이 좋지 않다는 것을 의미하므로 사용하지 않아야합니다.

기능이 좋지 않다는 것을 의미하지는 않습니다 (기능이 본질적으로 나쁠 수 없음). 단지 기능이 자주 잘못 사용되었다는 것을 의미합니다 (또는 직접 포인터 대 가비지 수집과 같은 기본 개념으로 인해 구현할 수 없음). 정의상 Java는보다 쉽고 프로그래머 친화적 인 것이 목표이므로 쉽게 남용 될 수있는 것으로 입증 된 기능을 제거합니다.

C ++ 관련 기능 (예 : 친구 기능, 다중 상속)이있는 C ++ 코드는 C ++ 프로그래머 만 유지 보수하거나 검토 할 수 있지만 C ++ 언어 별 기능없이 Java와 같은 C ++ 만 작성하면 코드를 유지 보수하거나 검토 할 수 있습니다. C ++ 및 Java 프로그래머

아 그래? 가장 간단한 C ++ 코드를 보자 :

int len = mystring->size();

"언어 별"기능을 사용하지 않았지만 Java 개발자가 이미 유지할 수없는 기능입니다! Java에서는 "."로 역 참조하기 때문에 여기 "->입니다.

언젠가 코드를 Java로 변환하라는 메시지가 표시 될 수 있습니다.

또는 C #. 또는 하스켈. 아니면 파이썬. 아니면 루비. 또는 COBOL (예, 가능합니다!). 미래를 어떻게 알 수 있습니까?

C ++ 전용 기능이없는 코드는 일반적으로 유지 관리가 용이합니다.

정확히 반대입니다. 프로그래밍을보다 쉽게 ​​유지 보수 할 수 있도록하기 위해 모든 기능이 도입되었습니다. 예 : 수레에서 작동하는 프로그램을 가져 가십시오. 이제 복잡한 숫자를 처리하도록 업그레이드하십시오. 구조에 작업자 과부하!

모든 C ++ 언어 별 기능 (예 : 다중 상속)에는 Java로 구현할 대안이 있어야합니다. 그렇지 않은 경우 디자인 패턴 또는 코드 아키텍처에 문제가 있음을 의미합니다.

그러나 Java에는 다중 상속이 있습니다! "인터페이스"라고합니다. 자바 구현은 모든 것을 파생 시켜서 끔찍한 다이아몬드를 피하는 문제 해결 방법입니다 Object. 그것은 interface어떤 유일한 목적이에서 파생되지 않는 것을 도입함으로써 이루어집니다 Object. C ++에는이 문제가 없었습니다. 필수 공통베이스가 없으므로 모든 클래스가 끔찍한 다이아몬드없이 인터페이스로 작동 할 수 있습니다.

참고 사항 : Java는 최근 인터페이스에 구체적인 메소드를 도입했습니다. C ++에는 항상 없었던 문제를 해결 해야하는 기능이 추가되었습니다.

또한 "C ++에는 있지만 Java에는없는 것"은 거의 언급하지 않았습니다. C ++과 Java의 가장 큰 차이점 중 하나는 메모리 레이아웃 제어입니다. Java와 마찬가지로 객체에 대한 포인터 배열을 만들거나 연속 메모리 블록을 만들 수 있습니다. 이제 Java 개발자를 오도 할 수있는 C ++ 기능에 대해 걱정하고 있다면 숨겨지고 미묘한 것이 여러 상속 또는 오버로드 된 연산자와 같은 첫 번째 시력에서 명백하고 인식 가능한 것보다 훨씬 높을 것입니다.

결론 : 깨끗한 코드는 깨끗한 코드입니다. Java 또는 C ++-동일한 차이점. 간단하게 유지하십시오. 불필요한 합병증은 잘못된 코드의 주요 원인입니다.


Java는 C ++의 모든 기능을 제공하는 언어에서 지원할 수없는 일부 기능 및 보증을 제공합니다. 예를 들어, 언어는 C ++에 포함 된 일반화 된 다중 상속 형식을 제공하면서 동적 유형로드 및 Java의 전체 ID 보존 캐스트를 허용 할 수 없습니다.
supercat

@ supercat 나는 왜 당신이 이것을 말하는지 이해하지 못합니다. 문제는 C ++로 재현 할 수없는 Java 기능에 관한 것이 아니라 Java가 버린 C ++ 기능에 관한 것입니다.
Agent_L

내 요점은 Java의 일부 기능이 C ++에 포함되어 있지 않지만 Java의 일부 기능은 C ++에 포함 된 다른 기능과 근본적으로 호환되지 않으므로 언어를 모두 지원하는 유형을 가질 수 없습니다 (C ++ / CLI와 같은 언어) C ++ 기능을 지원하는 유형과 Java-ish 기능을 지원하는 유형이 있지만 상호 운용성이 제한된 별도의 유니버스에 효과적으로 거주합니다.
supercat

6

아니요, 일반적으로 Java와 같이 C ++을 작성해서는 안되며 Java에는 없는 C ++ 언어 기능을 반드시 생략 해서는 안됩니다 .

우선, Java는 가비지 수집되므로 C ++ "delete"키워드에 해당하지 않습니다. 규칙에 따라 허용되지 않기 때문에 삭제하지 않고 프로그램을 구현하십시오.

축하합니다. 이제 메모리 누수가 있습니다.). 그것은 이론적 인 것도 아닙니다. 저는이 정확한 상황이 오픈 소스 게임에서 일어나는 것을 보았습니다.

마찬가지로 Java에는 많은 공통 함수 호출 규칙을 배제하는 C ++ 포인터와 같은 것이 없습니다 .

피해야 할 C ++의 기능이 있지만 (아래 참조) "Java에 있지 않음"은 좋은 리트머스 테스트가 아닙니다.


더 나은 지침은 다음과 같습니다.

  1. 언어, 환경 및 도구에 적합한 코드를 작성하십시오.
  2. 이 이해할 수있는 코드를 작성 하십시오 .
  3. 팀이 주어진 도메인에서 유능한 지 확인하십시오.

항목 (3)은 C ++에서 학습하지 않고 C ++에서 Java 프로그래머 코드를 가져서는 안됨을 의미합니다. 자바의 이상한 방언처럼 취급하려고 할 때 배우지 못할 수있는 미묘하지만 중요한 차이점이 있습니다.

항목 (2)는 이 다중 상속 (예 : 다중 상속)에 특히 불편하고이를 사용하지 않는 적절한 솔루션이있는 경우 대체 솔루션을 사용하는 것이 가장 좋습니다. 그러나 이것은 팀에 따라 다릅니다. 반면에 팀이 다중 상속보다 대체 솔루션에 더 불편한 경우 다중 상속을 사용하십시오!


마지막으로, 피해야 할 C ++의 언어 기능이 있습니다. 이것이 무엇인지 알고 싶다면 , 다른 언어의 프로그래머보다는 C ++ 프로그래머에게 물어보십시오 . 시작해야 할 몇 가지 예는 포인터 산술 (일반적인 합의 없음)과 goto입니다.


6

다른 답변에는 이미 몇 가지 좋은 점이 있지만 질문과 진술을 개별적으로 다루는 더 완전한 답변을 제공하고 싶습니다.


Java가 C ++에있는 기능을 제공하지 않으면 기능이 좋지 않다는 것을 의미하므로 사용하지 않아야합니다.

Java는 C ++의 "좋은 부분"이 아니며 그렇게 생각할 이유가 없습니다.

특히, 각각의 개별 C ++ 기능의 장점은 논란의 여지가 있지만 Java의 일부가 아닌 C ++ 11 / C ++ 14의 많은 기능이 Java 디자이너가 나쁜 생각으로 생각했기 때문에 반드시 배제 할 필요는 없습니다. 예를 들어, 버전 8까지 Java에는 람다가 없지만 C ++ 11 표준에서 C ++에 도입되었습니다. Java 8 이전에는 Java에서 누락 된 C ++ 기능이 "좋지 않음"으로 인해 설계 상으로 누락되었다고 가정했을 때 언어 기능으로서의 람다는 "좋지 않다"(LISPers의 공포에도 불구하고) 아마 당신이 실제로 Java를 좋아 한다고 들었을 정도로 충분히 끔찍할 것입니다 ). 그러나 이제는 Java 디자이너가 Stamp of Approval (TM)을 람다에 넣었으므로 이제는 좋은 것입니다.

Java 8에서도 좀 더 깊이 파고 들기 위해 람다로서의 람다는 C ++ 14의 람다만큼 융통성 없지만 이것은 더 유연한 접근 방식이 언어 디자인 관점.


C ++ 관련 기능 (예 : 친구 기능, 다중 상속)이있는 C ++ 코드는 C ++ 프로그래머 만 유지 보수하거나 검토 할 수 있지만 C ++ 언어 별 기능없이 Java와 같은 C ++ 만 작성하면 코드를 유지 보수하거나 검토 할 수 있습니다. C ++ 및 Java 프로그래머

이것이 내가 응답하고 싶은 주요한 것입니다.

광범위하게 말하면, 사용하는 언어에 친숙하지 않은 프로그래머로부터 코드 검토를 얻는 것이 가치가있을 수 있습니다. 함수 / 메소드 이름 및 주석의 명확성에 대한 귀중한 피드백을 제공 할 수 있으며, 언어가 이미 알고있는 하나 이상의 언어와 유사하면 기본 프로그램 흐름을 따를 수 있습니다. 잠재적으로 논리 오류를 포착합니다.

그러나 이러한 종류의 검토가 실제로 사용중인 언어를 알고있는 개발자의 검토만큼 "좋거나"동등한 경우 는 아닙니다 . 본질적으로 이것은 한 언어를 다른 언어 처럼 보이게 만드는 것은 일반적으로 미묘한 차이를 숨기고, 한 언어를 다른 언어 처럼 행동 하게 만들면 (특히 C ++ 및 Java의 경우) 언어에 대해 관용적이지 않거나 여전히 혼란 스러울 수 있기 때문입니다. 검토자를 위해.

먼저 C ++을 "와 같이"Java로 만드는 것이 무엇을 의미하는지 생각해 보자. 간단한 경우, newJava에서와 같이 객체를 인스턴스화 하는 데 사용할 수 있습니다 .

Foo foo = new Foo();

그러나 객체 를 호출 하는 ->대신 이 방법으로 인스턴스화 된 객체 .는 메소드 호출 을 Java처럼 보이게하려면 대신 다음과 같이 작성해야합니다.

Foo& foo = *new Foo();

그러나 이것은 관용적이지 않다. 특히, 메모리는 나중에 사용하여 청소해야 delete &foo하는 몇 가지 경험이 풍부한 C ++의 devs도 법적 코드를 실감하지 않을 수 있습니다 . 어느 쪽이든, 전체에 뿌려 재미 비 Java와 같은 상징이있다, 그래서 우리는 할 수없는 매우 언어가 자바 "처럼"합니다. ( , 또는 더 나쁜을 *new사용하여 제거 할 수는 있지만 동료 개발자가 당신을 미워하라고 간청하고 있습니다.) 위에서 언급했듯이 Java에는 존재하지 않으므로 어떤 경우에도 (다른 답변에서 언급했듯이) ) 실제로 메모리 누수없이 객체 사용을 "보기"할 수 없다.#define New *new#define new *newdelete

그러나 최신 C ++에는 스마트 공유 포인터가 포함되어 있는데, 이는 Java의 메모리 관리 변수 참조와 매우 유사합니다. 따라서 Java의 어느 곳에서나 쓸 Foo foo = new Foo();수 있으며 대신 쓸 수 있습니다.

std::shared_ptr<Foo> foo = std::make_shared<Foo>();

이제 실제로 Java와 비슷한 언어 기능을 사용하고 있습니다. 그러나 갑자기 비 C ++ 검토 자에게 설명 할 것이 많습니다.이 내용은 무엇 shared_ptr입니까? 미묘한 까다로운 "gotchas"는 make_shared무엇입니까? (완전한 전달을 사용하는데, 일부 실패 사례가 있으며 "잘못된"생성자가 호출 될 수 있습니다.) 메소드를 호출해야하는 이유는 ->있지만 .컴파일러가 일부 메소드를 사용 하는 것이 허용되는 이유는 무엇 입니까? ( shared_ptr자신의 방법이 있습니다.) 방법이 있다면 Foo::reset(void)존재 부주의 개발자가 그것을 호출 할 수 있습니다 foo.reset()(의 인스턴스에 하나 개의 공유 포인터를 가리키는이있는 경우, 이는 Foo호출이 발생했을 때) 기본 메모리를 삭제하고 무효화 것 foo, 그리고 Java 개발자는이 문제를 잡을 가능성이 없습니다.

또한, C ++은많은함정 입니다 특정 받는 언어를. 내가 알 수있는 바와 같이, 대부분의 C ++ 개발자는 "안전한"C ++ 관행에 대한 고유 한 관용구를 점진적으로 개발함으로써 이러한 함정을 다루는 법을 배웁니다. Google 코딩 실무 및 이에 대한 의견은 "시즌 C ++ 전문가는 일반적으로 Google 코딩 가이드 라인을 거부합니다"). 언어가 너무 복잡하다고 주장하는 모든 주장은 (적어도 내 경험 상으로는) "잘 사용하지 마십시오." 나는 이것이 C ++ 커뮤니티에 대한 매우 부정적인 견해임을 알고 있으며 언어 학습자를 도울 기꺼이 경험이 풍부한 개발자 있지만 실제로 예를 들어 정의되지 않은 행동에 대한 확실한 방어력 인 것 같습니다 (예를 들어 위의 '내 함정'링크에서 많은 토론을 참조하십시오).

Java 개발자는 코드 검토를 통해 이러한 함정을 찾고 수정하는 데 도움이되지 않습니다.


언젠가 코드를 Java로 변환하라는 메시지가 표시 될 수 있습니다.

설계 단계에있는 동안 향후 코드에 발생할 수있는 사항을 고려하는 것은 전적으로 유효합니다 (추천 가능, 심지어 짝수).

그러나 먼저,이 특별한 고려 사항은 원격 가능성처럼 보입니다. 코드는 일반적으로 그대로 재사용되거나 (예를 들어, 작동중인 C ++ 코드의 일부 또는 전부를 JNI 인터페이스를 사용하여 일부 미래 Java 소프트웨어에 꽂을 수 있음) 완전히 재 작성됩니다 직접 "전사"보다.

두 번째로 나중에 말하세요

모든 C ++ 언어 별 기능 (예 : 다중 상속)에는 Java로 구현할 대안이 있어야합니다.

이것은 본질적으로 "Java로 변환"포인트를 취소합니다. 소프트웨어가 관용적 C ++로 작성된 후 관용적 Java로 변환되는 경우, C ++ 기능의 정확한 일대일 매핑을 Java 기능에 적용하여이 변환을 수행 할 것이라고 기대할 이유가 없습니다.


C ++ 전용 기능이없는 코드는 일반적으로 유지 관리가 용이합니다.

여기서 의미하는 바가 명확하지 않지만 실제로는 일부에 동의합니다. 매우 조심하지 않으면 C ++ 기능을 사용하면 유지 관리 성 문제가 발생할 수 있습니다. C ++ FQA 라이트 (언어 적어도 실제로 꽤 잘 이해하기 위해 나타납니다 누군가로부터 지지자의 중요 웹 사이트)을한다고

... 개발자의 80 %는 최대 20 %의 언어를 이해합니다. 사람들마다 20 %가 같지 않으므로 서로의 코드를 이해한다고 믿지 마십시오.

참고 사항 : C ++ 팬이라면 내 대답 에서이 시점에 도달하고 FQA 작성자가 실제로 C ++을 이해하지 못하거나 대부분의 주장에 불분명하다고 주장하기 위해 의견으로 뛰어 드는 경향이 있다면 , (1) 인용 한 후 정확히 두 문장으로 FQA가 매우 치우친 출처임을 인정하고, (2) FQA 작성자가 C ++을 이해하는지 여부를 말하려는 것은 중요하지 않습니다. 그리고 C ++을 bash하려고하지 않으며 FQA를 인용했기 때문에 anti-C ++라고 가정하지 않고 나머지 게시물을 읽어야합니다. 메모 끝.

마찬가지로, Linus Torvalds 는 본질적으로 이러한 이유로 C ++을 싫어합니다 (경고 : 링크는 악명 높은 Linus 스타일의 맹세를 포함합니다).

분명히 이것들은 문제에 대해 매우 편견이 있지만 C ++ 지지자조차도 종종 언어 기능 세트 전체를 사용해서는 안된다고 말합니다 (다시 한번 Google 코딩 지침 참조; C ++ 제작자 Bjarne Stroustrup , "C ++에는 훨씬 더 작고 깨끗한 언어가 있습니다.")

따라서 특히 Java 배경에서 오는 경우 C ++ 기능을 오용하기가 너무 쉽다는 생각에 약간의 장점이 있다고 생각합니다. 또한, 자신을 언어의 일부로 제한함으로써 이러한 문제를 완화시키는 아이디어가 있습니다.

그러나 "다른 언어"가 C 가 아닌 한 다른 언어를 기반으로 사용할 하위 집합을 결정 하는 것은 올바른 접근 방식으로 보이지 않습니다 . C ++ 언어에는 실제로 C와 유사한 하위 집합이 있기 때문입니다. (Linus는 위의 그의 말에 이것을 언급하고, Scott Meyers는이 서브셋을 "하위 언어"라고도합니다.) Java의 런타임 패러다임 (가비지 수집, VM에서 실행)은 C ++과 근본적으로 다르기 때문에 C ++ 사용법에 대한 유용한 교훈이 명확하지 않으며 위에서 언급했듯이 Java에서 직접 C ++에 대한 교훈을 얻으려고 시도하면 비 관용적 코드가 될 수 있습니다.

대신 언어를 관용적으로 사용하는 방법에 대한 이해를 바탕으로 언어의 "허용 가능한 부분 집합"을 정의하십시오. C가 제공하는 것 이상의 많은 C ++ 기능을 여전히 활용하는 상당히 제한적인 부분 집합을 원한다면 위에서 언급 한 Google 코딩 가이드 라인을 시작하는 것이 좋습니다. 물론 Google의 일부 제한에 대해 "합리적인 주장"이 없다고 말하는 개발자가 있지만 D 언어에 대한 그의 작업에서 Alexandrescu를 고용하지 않는 한 (그 자체로 무언가를 말해야 함), 그렇지 않습니다. 아마 괜찮을 것입니다. C ++를 Java로 바꾸는 것보다 확실히 낫습니다.

일련의 코드 지침에 대한 또 다른 좋은 출발점은 Bjarne Stroustrup과 Herb Sutter가 진행중인 새로운 C ++ 핵심 지침 입니다.

C ++의 단점을 해결하는 유일한 방법은 다른 언어를 선택하는 것입니다. 당신이 자바를 좋아하는 것처럼 들리며,이 프로젝트가 결국 자바로 변환 될 가능성이 있다고 생각합니다. 다른 답변에서 언급했듯이 Java로 시작할 수 있습니다.

당신이 정말로 진정한 이유를 두 가지 이유가 있습니다 필요가 자바 이외의 것을 사용하려면 :

  1. 실제로 런타임 성능이 필요합니다. 이 경우 공유 포인터와 같은 Java와 같은 기술이 런타임 성능을 저하시키기 때문에 C ++을 Java처럼 처리하는 것이 실제로 도움이되지는 않을 것입니다.
  2. 아직 JVM을 지원하지 않는 모호한 플랫폼에서 작동하려면 소프트웨어가 필요합니다. 이 경우 GCC 또는 Clang 프런트 엔드가있는 언어가있을 수 있습니다. C와 C ++는 명백한 후보이지만 Rust와 같은 것을 살펴볼 수도 있습니다. (빠른 플러그 : Rust를 광범위하게 사용하지는 않았지만 멋지게 보이고 가능한 한 빨리 주요 Rust 프로젝트를 수행하기를 열망하고 있으며 C ++ 프로젝트를 시작하려는 모든 사람들이 Rust를 대안으로 고려해야한다고 생각합니다.)

모든 C ++ 언어 별 기능 (예 : 다중 상속)에는 Java로 구현할 대안이 있어야합니다. 그렇지 않은 경우 디자인 패턴 또는 코드 아키텍처에 문제가 있음을 의미합니다.

이미이 문제를 해결했지만 의도적으로 두 번째 문장을 생략했습니다.

constexprJava와 같은 부분적으로 JIT 언어에서 의미가없는과 같은 것이 잘못된 아키텍처의 표시 라고 확신 하지 않습니다. 템플릿 메타 프로그래밍을 과도하게 사용하는 것이 가치가있는 것보다 더 문제가 될 수 있다는 생각에 더 개방적입니다. 특히 지금은 constexpr컴파일 타임 함수 평가를 수행하기 위해 존재하지만, 디자인 결함 constexpr이없는 경우에는 분명 합니다. '을 사용하여 다시 : 당신은 단순히 어떤 계산도 멋진 성능 향상이 코드를 실행하기 전에 발생하는 것을 보장 (예를 들어 볼 수있는 벤치 마크 게임의 다체 문제에 대해이 항목 또 다른 하나를 제외하고 다른 모든 항목을 능가하는 성능, C ++로 작성


5
FQA 저자는 확실히 "언어의 최대 20 %를 이해"그룹에 속합니다. 거기에 사실 틀린 꽤 많은 답변이 있으며, 짚맨 다음에 strawman으로 묘사 된 요점을 놓치지 않는 많은 무리가 있습니다.
Ben Voigt

2
C ++ FQA의 불만 (대부분의 모든 것)은 말이되지 않습니다. 현대 언어는 엄청납니다. C ++은 Python, Ruby, Perl 및 Java에 비해 다소 작습니다. stackoverflow에서 해당 언어로 기본 질문을하고 첫 번째 대답은 필연적으로 "왜 그렇게하지 않았 습니까?"라는 import SomeVeryBasicPackage문구를 따라야 합니다 . 고급 질문을하면 첫 번째 답변은 "왜 안 되었습니까?"라는 import SomeMagicalPackage문구를 따라야 합니다 .
David Hammen

1
@DavidHammen 80/20 분할은 표준 라이브러리 구성 요소뿐만 아니라 핵심 언어 기능을 의미한다고 생각합니다.이 경우 Perl을 제외하고 언급 한 언어는 실제로 C ++만큼 크거나 복잡하지 않은 것 같습니다. 어쨌든, 그것은 내 대답의 아주 작은 부분이며, 그것이 편향 된 출처라는 것을 인정했습니다.
Kyle Strand

1
VM / 관리 언어는 표면적으로 훨씬 더 복잡하지만 사용 관점에서는 복잡합니다.
Kyle Strand

1
내 경우에는 분명히 C ++과 C를 별도로 배웠지 만 C ++ 클래스는 정말 철저했습니다. 그러나 20/80 분할에 대한 완전한 인용은 모든 프로그래머가 언어 의 다른 20 %를 알고 있다는 것인데, 대부분의 프로그래머는 언어의 C 부분을 독립적으로 배우는 것으로 설명하지 않습니다. 어쨌든 C ++ 이보다 강력한 프로그래밍을 허용하는 방법을 자세히 설명하고 싶다면 (이전에는 보았지만 이해하지 못함) 채팅방이나 주석이 아닌 다른 방에서하는 것이 가장 좋습니다. .
Kyle Strand

5

프로젝트의 환경에서 C ++을 사용하도록 제한되어 있다고 가정하십시오. C ++에는 있지만 Java에는없는 일부 언어 기능 (예 : 다중 상속, 연산자 재정의)의 사용을 방지하는 것이 좋습니까?

아니.

"프로젝트 환경에 따라"C ++를 사용하는 것으로 제한되어 있다면, 개인적으로 사용 / 복음화를 얼마나 선호하고 / 희망하든 다른 기술 에 대해서도 생각할 필요가 거의 없습니다.
"Technology X"또는 "Y"가 특정 기능을 지원하는지 여부는 C ++ 응용 프로그램을 빌드하는 방식과 관계없습니다 .
아마도 "좋은 이유"(현재 또는 과거) 위한 C ++ 응용 프로그램이므로 특정 "도구 상자"가 제공하는 모든 것을 사용하여 C ++ 응용 프로그램 으로 작성해야 합니다.

만약 때 (다음 포트에 대한 요구 사항을 다른 기술에 응용 프로그램을 거기 에만 다음) 다른 플랫폼의 기능을 고려할 수 있습니다. 뭔가 일어날 지도 모른다 는 오프-기회에 "코를 잘라 얼굴을 뱉을"지점은 없다 . 그러나 도매 재 작성은 비용이 많이 들고 위험한 작업이라는 점을 명심하십시오.

몇 년 전 Visual Basic [.Net] World에서 비슷한 ( "사용 또는 사용하지 않음") 토론이있었습니다. 여기서 누군가는 [핵심 언어]를 사용하지 않고 Visual Basic 응용 프로그램을 작성해야한다는 밝은 생각을 가지고있었습니다. Microsoft.VisualBasic 네임 스페이스에서 제공하는 기능 std :: namespace없이 C ++ 애플리케이션을 작성하는 것과 같습니다. 그래, 가능하지만 왜 지구상에서 올바른 생각을 가진 사람이 귀찮게 할까?


1
Visual Basic에 대한 마지막 요점 : 이러한 공급 업체 라이브러리 의 문제점 은 독점적이라는 것입니다. 그것들을 사용한다는 것은 자신을 그 벤더에게 연결시키는 것을 의미합니다. 공급 업체는 연결을 원하지만 장기적으로는 그렇지 않습니다. 공급 업체별 기능에 의존하는 모든 것을 다시 쓰지 않으면 다른 공급 업체의 소프트웨어를 사용할 수 없습니다. 공급 업체별 기능을 많이 사용할수록 공급 업체 변경 비용이 높아 지므로 공급 업체가 사용자를 강제로 변경할 수 있습니다. 이것이 바로 자유 소프트웨어가 자유 소프트웨어와 같이 중요한 이유 중 하나입니다.
cmaster

Microsoft.VisualBasic네임 스페이스 것은 억지이다. 마지막으로 사용한 지 몇 년이 지났지 만, 적어도 처음에는 VB6과의 하위 호환성 (및 / 또는 VB6 프로그래머가 "집에서"느낄 수 있도록하는 것)을 목표로하고있었습니다. 대부분 나머지 프레임 워크에서 이미 더 현대적이고 통합 된 형태로 이미 제공되었던 기능을 제공했기 때문에 새 프로젝트에서는 거의 사용하지 않는 것이 좋습니다. 반대로 std::네임 스페이스는 전체 표준 라이브러리가 상주하는 곳입니다. .NET에서 전체 BCL을 피하는 것과 같습니다.
Matteo Italia

2

현재 답변은 사용하는 언어를 활용하고 왜 C ++ 기능이 왜 jave에 있지 않기 때문에“나쁜”지 설명하지 않기 때문에 이것이 나쁜 일이라고 말합니다. 나는 이것을 다른 각도에서 대답 할 것이다.

다중 상속, 연산자 오버로드 및 자체 템플릿 정의와 같은 복잡한 C ++ 기능을 피하는 것이 좋습니다.

그러나 가장 간단한 작업보다 더 많은 문제는 다음과 같습니다.

  • 메모리를 할당하고
  • 그 돈을 포인트와 연결
  • 데이터 구조를 구축
  • 안전 할 때 메모리를 재사용 할 수 있습니다.

위의 내용을 허용하는 Java 및 C ++의 공통 하위 집합이 없으므로 요청하는 것이 불가능합니다. (자바와 C #에 대해 묻는다면 둘 다 가비지 수집기를 사용하기 때문에 훨씬 좋은 기회가 될 것입니다.)

그러나 Java 개발자가 무엇을하고 있는지 (상세한 "방법"은 아님) 이해할 수 있도록 코드를 작성해야 할 수 있으며 이는 합리적입니다.

C ++과 JAVA에서 모두 구현 한 고유 한 언어를 디자인 할 수도 있습니다 .....


0

다른 코더들이 이해하지 못하는 코드를 작성해서는 안됩니다. 언어 잠금이 문제라고 생각되면 개발자 잠금이 나타날 때까지 기다리십시오. 하나는 다른 것보다 당신을 인질로 잡을 가능성이 높습니다.

기술적 인 이유는 없습니다. 당신이 만든 것은 어떤 이유로 든 언어가 사용되었지만 현재와 미래의 많은 개발자들이 실제로 그것을 이해하지 못하는 시나리오입니다.

내 생각에, Java 개발자는 Java로 작성하는 방식으로 C ++을 작성할 가능성이 높으므로 규칙으로 만드는 이유는 무엇입니까? Java 개발자를 위해 작은 C ++ 명령어 / 문서를 사용하면 구현 및 유지 관리가 더 쉬운 일부 C ++ 관련 기능을 발견 할 수 있습니다.

이것은 기본 프로그래머가 객체 지향 언어로 이동하는 문제에 대한 논쟁이었습니다. OOP 관행을 이해하지 못하는 새로운 개발자를 해칠 때 OOP 관행을 구현하는 것이 아니라 전혀 구현하지 않습니다. 그렇게하면 대개 잘못됩니다. 잘못 수행 된 경우 이유와 상관없이 제거해야합니다.

맹목적으로 코드를 복사하여 붙여 넣는 사람 외에는 어쨌든 이해하지 못하는 많은 영역에서 코드를 작성합니다.

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