프로그래밍/C,C++

C++과 C# 비교 차이점

gameObject 2023. 5. 30. 00:21
728x90

앞으로 C++ 과 C#, 최종적으로는 Unity를 공부하여 게임을 개발할 학생으로써

같은 C인데 뭐가 다른지 궁금하여 유튜브에 검색하다보니

굉장히 좋은 영상이 있어 아직 많은 개념을 모르지만 맛보기 해보려고 한다.

https://www.youtube.com/watch?v=AZrD7FltQ5I

추후 C++과 C#을 어느정도 다루고 나서 이 글을 다시 보며

개념에 대해 깊이 이해할 수 있는 시간을 갖고싶다.

 

기본적으로 C언어에서 파생되었다고 보면 된다.

C >> C++ >> C#

 

차이점

1. 컴파일 환경

1) C++은 컴파일 후 어셈블리어로 만들어진다.(저수준언어_기계에 밀접, 운영체제 or CPU에 영향을 받음)

2) Microsoft가 이런 구조를 벗어나려고 만든것이 C#이다.(크로스 플랫폼)

   .NET을 개발 (가상머신)

따라서 우리가 만든건 기계에 가까운 언어 어셈블리어 위에 .NET이 올라가있음

사람 - C# - .NET - 어셈블리어 - 기계 / IL이라고 보면됨.

 

플랫폼 : c++은 중립적, c#은 .NET플랫폼

코드를 한번만 작성하면 여러플랫폼에서 사용할 수 있게됨.

 

Just in Time (JIT) 컴파일러 .NET이 실시간으로 컴파일을 함. 즉 엄청나게 컴파일이 빠름

 

2. 값 & 참조 타입

사실 언어적인 특성으로 다른개념을 쓰고있어 비교하기가 애매하지만 간단히 비교를 해보면

1) 값타입 : C++는 정적할당 / C#은 기본타입 구조체

2) 참조타입 : C++은 동적 할당 참조형 / C#은 클래스

C++은 언어의 문법적인 특성으로 값인지, 참조인지 나눠지지만

C#은 타입, 즉 기본타입 구조체는 값이고 클래스는 참조로 명확하게 나뉘어져 있음

 

3. 메모리 관리

C#은 메모리를 자동으로 관리해줌

C++은 동적으로 할당하고 할당한 메모리를 해제하는것은 프로그래머의 몫

(모던 c++에서는 스마트포인터라는것이 있기는 함)

 

동적할당 C++ 포인터 / c# 참조형

메모리해제 C++ 수동 / c# Garbage Collector(자동으로 메모리를 주기적으로 체크하며 청소해줌)

---> 통곡의 벽 포인터라는 문법이 C#에서는 없어짐

인스턴스 생성 C++ 모든타입 / C#은 참조타입

 

4. 흐름제어

형태는 비슷하지만 편의성에서 기능의 차이가 있음

1) IF구문

 - C#에서 차이점이 생겼음, 값 타입들 중 bool인 타입만 참,거짓을 판단 할 수 있음.(프로그래밍의 모호성_Ambiguity 제거)

 - 조건문이 if에만 있는것이 아님. while등에 있는데 bool인 타입만 참,거짓 판단할수 있다는것이 포인트

2) switch구문

 - c#에서 굉장히 강력해짐

 - 레이블에 문자열을 쓸 수 있음(c++보다 유연한 코딩이 가능)

 - C#에서는 레이블에서 break가 없으면 명령 수행 후 통과를 할 수 없음.(C++에서는 case0수행후 break이 없으면 case1로 넘어가서 두가지 모두 실행됨) >> 사용자가 실수할 확률을 C#에서 수정_에러가 남

 - C# 컬렉션기능 (C++에서는 컨테이너)

 

5. 구조체

의미 : c++ 모든 멤버가 public인 class / C#은 값타입

생성자 : C++구조체는 생성자로 쓸수있음 / C#은 안됨

파생 : C++ 구조체는 파생으로 쓸수있음 / C#은 안됨

 

C#에서의 구조체는 오직 데이터들만 캡슐화 하기 위한 용도로 사용되며 값 타입으로 취급된다.

 

6. 클래스

가장큰 차이점은 C++은 메모리 관리를 프로그래머가 직접하기 때문에

소멸자가 C++은 필요 / C# 은 필요 없다.(자동으로 제거해주기 때문)

파생.  C++은 다중상속 / C#은 단일 상속(public상속)

(c#을 사용하며 소멸자가 없어서 답답하다면, IDisposal 인터페이스와 using을 공부해보자_약간은 답답함 해소)

 

상속에서 public상속만 지원한다 =? 어떤의미인가

>> C++은 접근제한자를 두어 상속할때 어떻게 접근할 지 만들수가 있음(protected)

C#은 상속에 대한 접근 제한자가 없다.(is-a관계, has-a 관계)

(OOP를 처음 배우는사람들이 가장 많이 하는 실수중의 하나는 모든 객체를 상속으로만 하려고 한다는 것이다.

차와 엔진의 관계는 상속보다 has-a관계가 편할 수 있음, 즉 들고있으면 된다.)

 class Car {

}

 

class ElectricCar : Car

이렇게 되어있다면 ElectricCar:Car 에서 뒤에오는 Car는 기본적으로 public이다. > 이것만 지원

 

다중상속(자식이 두개의 부모를 가질 수 있음)

- 다이아몬드 상속이라는 단점이 하나 있어서 C#에서 막음 (모호함이 심해서)

- C++에서 물론 해결방법이 있으나 (인터넷에서 찾아보면 Virtual keyword..등) 모호성이 높아지는건 어쩔 수 없다.

 

C#은 부모를 두개를 받을 수 없음(다중상속 허용 x)

단, interface에서는 다중상속이 가능(메서드 선언들로만 이뤄진 약속)

>> c++에서 interface는 순수 가상 함수들로 이루어진 추상 클래스

즉 규격만 있고 정의가 없기때문에 중복될 일이 없기때문에 여러개 받을 수 있음

 

7. 일반화 프로그래밍

c++는 기본적으로 스트롱타입, 즉 강력한 타입을 사용한다고 보통 부르는데 프로그래머가 명시적으로 타입을 지정하거나, 컴파일러가 추론, 예상가능한 특정 형식만 사용가능함. 

프로그래밍을 하며 자료구조나 알고리즘을 살펴보다 보면 대부분의 자료구조나 알고리즘은 특정한 타입과 상관없이 모든 타입에 다 작동하고 동작함.

그래서 자료구조와 알고리즘을 만들다 보면 일반화시킨 모든타입에서 동작하는 형태가 필요해지는데 이걸 

C++에서는 템플릿이라는 개념을 사용하고 있음. >> 이걸 일반화라고 부른다.

 

차이점

시점: C++은 컴파일시점에 특수화 시켜줌 / C#은 Runtime

방식: C++는 코드 확장 / C#은 메타데이터라는 특수한 타입을 사용

명칭: C++는 템플릿 / C#에서는 제너릭

 

C++은 템플릿에서 에러의 원인찾기가 정말 어려움(STL을 배우기 어려운 이유)_코드 확장되기 때문에 에러를 찾기 어려움

C#은 컴파일타임에 에러가 발생을 하면 상대적으로 찾기 쉬움(단, 기능이 제한된다._c++은 유연함)

 

8. Boxing & UnBoxing _ 중요

포장하다 / 포장을 풀다

기본적으로 값타입 참조타입이 있는데

당연히 값타입을 전달하는 것보다. 참조, 즉 메모리의 주소만 전달하는것이 효율적이다.

(c++에서 값에 의한 호출_call by value, 참조에 의한 호출_call by reference)

 

c#은 값타입과 참조타입을 프로그래머가 제어할 수 없으므로 이 과정들이 자동으로 일어나는 경우가 있다.

(C# 값타입은 일반형타입과 구조체로 고정되어있고 참조타입은 클래스로 고정되어있음)

 

Boxing의 뜻은 쉽게말해, x라는 값이 있다면 이것을 박스에 담아서 전달하는것이 효율적이라는 뜻이다.

값을 전달하기 위해 값을 참조타입에 담은 다음 전달한다는것

그 박스를 받고 푸는것이 unboxing이다.

 

언박싱은 꺼낼때 값의 타입을 명확하게 지정을 해줘야한다.(타입을 꺼낼때 올바르게 검사하기 위함)

int value = 100;

object obj = value;

int k = (int)obj;

 

마이크로소프트 문서에는 일반 레퍼런스 참조형(클래스)로 만든 친구를 전달하는 것보다

Boxing : 20배 느리다.

UnBoxing : 4배 느리다.라고 명시가 되어있다.

따라서 성능에 민감한 게임에서는 이런 개념을 알고 있는지 아닌지가 중요하다.

boxing, unboxing을 피하는 방법 영상을 한번 다시 보면 알 수 있지 않을까 싶다.(IL2CPP)

(유니티에서 IL2CPP로 변경, 옛날에는 앱스토어에 올리려면 64가 나와야해서 IL2CPP로 만들수 밖에 없었다고 함)

 

느낀점

단순히 어떤 차이점이 있겠구나~ 라고 생각만 들었던 것이 명확해지는 순간이었던것 같다.

이전에 Flutter를 살짝 공부하며 한 언어에 정통하면 다른언어들은 비교적 쉽게 익힐 수 있다는 얘기를 들었는데

굉장히 추상적으로 느껴졌었다. 그때 공부한 dart언어의 문법들이 새록새록 생각이 나면서 언어들이 비슷하구나 라는 생각이 들었고

이번에 C++과 C#의 자세한 차이점을 들으며 C, C++, Java, dart, python등 언어들이 각자 차이점들이 많이 존재하겠구나 싶었다.

한가지 언어에 먼저 정통하고 메모리, OS등 컴퓨터 사이언스에 대한 이해 등의 전체적인 구조가 머리에 짜여져서

새로운 언어들을 습득하거나 공부할때 더욱 효율적이고 상세한 공부를 하여 필요한 프로젝트에 좋은 기여를 할 수 있는 사람이 되도록 노력해야겠다.

 

 

728x90