다른 답변에는 이미 몇 가지 좋은 점이 있지만 질문과 진술을 개별적으로 다루는 더 완전한 답변을 제공하고 싶습니다.
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로 만드는 것이 무엇을 의미하는지 생각해 보자. 간단한 경우, new
Java에서와 같이 객체를 인스턴스화 하는 데 사용할 수 있습니다 .
Foo foo = new Foo();
그러나 객체 를 호출 하는 ->
대신 이 방법으로 인스턴스화 된 객체 .
는 메소드 호출 을 Java처럼 보이게하려면 대신 다음과 같이 작성해야합니다.
Foo& foo = *new Foo();
그러나 이것은 관용적이지 않다. 특히, 메모리는 나중에 사용하여 청소해야 delete &foo
하는 몇 가지 경험이 풍부한 C ++의 devs도 법적 코드를 실감하지 않을 수 있습니다 . 어느 쪽이든, 전체에 뿌려 재미 비 Java와 같은 상징이있다, 그래서 우리는 할 수없는 매우 언어가 자바 "처럼"합니다. ( , 또는 더 나쁜을 *new
사용하여 제거 할 수는 있지만 동료 개발자가 당신을 미워하라고 간청하고 있습니다.) 위에서 언급했듯이 Java에는 존재하지 않으므로 어떤 경우에도 (다른 답변에서 언급했듯이) ) 실제로 메모리 누수없이 객체 사용을 "보기"할 수 없다.#define New *new
#define new *new
delete
그러나 최신 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로 시작할 수 있습니다.
당신이 정말로 진정한 이유를 두 가지 이유가 있습니다 필요가 자바 이외의 것을 사용하려면 :
- 실제로 런타임 성능이 필요합니다. 이 경우 공유 포인터와 같은 Java와 같은 기술이 런타임 성능을 저하시키기 때문에 C ++을 Java처럼 처리하는 것이 실제로 도움이되지는 않을 것입니다.
- 아직 JVM을 지원하지 않는 모호한 플랫폼에서 작동하려면 소프트웨어가 필요합니다. 이 경우 GCC 또는 Clang 프런트 엔드가있는 언어가있을 수 있습니다. C와 C ++는 명백한 후보이지만 Rust와 같은 것을 살펴볼 수도 있습니다. (빠른 플러그 : Rust를 광범위하게 사용하지는 않았지만 멋지게 보이고 가능한 한 빨리 주요 Rust 프로젝트를 수행하기를 열망하고 있으며 C ++ 프로젝트를 시작하려는 모든 사람들이 Rust를 대안으로 고려해야한다고 생각합니다.)
모든 C ++ 언어 별 기능 (예 : 다중 상속)에는 Java로 구현할 대안이 있어야합니다. 그렇지 않은 경우 디자인 패턴 또는 코드 아키텍처에 문제가 있음을 의미합니다.
이미이 문제를 해결했지만 의도적으로 두 번째 문장을 생략했습니다.
constexpr
Java와 같은 부분적으로 JIT 언어에서 의미가없는과 같은 것이 잘못된 아키텍처의 표시 라고 확신 하지 않습니다. 템플릿 메타 프로그래밍을 과도하게 사용하는 것이 가치가있는 것보다 더 문제가 될 수 있다는 생각에 더 개방적입니다. 특히 지금은 constexpr
컴파일 타임 함수 평가를 수행하기 위해 존재하지만, 디자인 결함 constexpr
이없는 경우에는 분명 합니다. '을 사용하여 다시 : 당신은 단순히 어떤 계산도 멋진 성능 향상이 코드를 실행하기 전에 발생하는 것을 보장 (예를 들어 볼 수있는 벤치 마크 게임의 다체 문제에 대해이 항목 또 다른 하나를 제외하고 다른 모든 항목을 능가하는 성능, C ++로 작성