프로그래밍 언어 113

Casting - 왜 C스타일 캐스팅은 4개로 나뉘었을까?

캐스팅(형 변환, Casting)캐스팅은 형변환 하는 것을 말한다. 암시적(Implicit)캐스팅프로그래머가 명시적으로 형 변환을 안할 경우에,알아서 컴파일러가 형변환을 해준다.단, 형변환이 허용되는 변환일 때에만 작동한다. 당연히, 프로그래머가 명시적 형변환을 할 때에는컴파일러가 개입하지 않으므로 암시적 캐스팅은 일어나지 않는다. 예시 코드int number1 = 3;long number2 = number1;  명시적(Explicit) 캐스팅 C++ 캐스팅의 종류static_castconst_castdynamic_castreinterpret_cast C 스타일 캐스팅이 C++에서 4가지로 나뉜 이유int score = (int)someVariable; 위 코드는 대체 무얼 할까? 위 코드는 C++ 스타..

인터페이스

C++ 에는 인터페이스가 없다.따라서 추상클래스로 인터페이스를 구상한다.근데 추상클래스와 인터페이스는 어떻게 구분할까?Interface와 abstract의 차이는 Interface는 함수만 있다는 것이다.또한 인터페이스는 다음과 같이 정의한다. // IFlyable.hclass IFlyable{public: virtual void Fly = 0}; 인터페이스는 클래스 명 앞에 I라는 대문자를 붙여준다.이는 인터페이스임을 명확하게 하기 위해서이다. 또한 함수는 순수가상함수로 만들어준다.인터페이스는 다중 상속을 허용한다.  인터페이스 정리 인터페이스C++은 자체적으로 인터페이스를 지원하지 않는다.순수 추상 클래스를 사용해서 Java의 인터페이스를 흉내낸다순수 가상 함수만 가진다멤버 변수는 없다. 근데 C++..

가상 소멸자와 비 가상 소멸자

비 가상 소멸자가상 소멸자를 안쓰는 경우는 어떻게 될까?가상 소멸자가 뭐길래, 가상 생성자는 없으면서가상 소멸자가 메모리 누수를 방지한다고 할까?왜 소멸자에 가상 키워드를 넣어야할까? 그에 대한 예시를 다음과 같이 추상화한 그림을 통해 알아보자. myCat이 delete될 경우(virtual 소멸자가 아닌 경우) 왜 그럴까?전에 정리한 가상 테이블을 기억해내면 금방 왜 그런지 알 수 있다. 만약 virtual 키워드를 붙였을 경우 즉 자신의 실 자료형에 맞는 소멸자를 호출하기 위함이다. 가상 소멸자는 매우 중요하다.반드시 유의할 점은,모든 클래스마다 가상 소멸자를 꼭 써줘야 한다.근데 가상함수 느리다면서가상 소멸자가 있는 클래스를 상속받지 않아도 이러라고? 싶을 수 있다. 근데 업캐스팅 해서 쓸 때,부모..

다형성(Polymorphism)

poly 라는 것이 여러 개라는 뜻을 가지고 있다. 그럼 morphi는 뭘 뜻할까? 모습이란 뜻을 가지고 있다. 여러 모습 즉 다형성이다. 개체지향 프로그래밍에서 많이 쓰이는 것이 다형성이다. 다형성을 배우기 전에, 멤버 함수에 대해 알아보자. 멤버 함수에 대해 말해 보자.다음 그림은 코드를 예시로 어떻게 스택과 힙에 메모리가 적재되는지 추상적으로 가시화한 것이다. 멤버 함수의 메모리 멤버 함수도 메모리 어딘가에 위치해 있다. (사실 사용되는 모든 정보는 메모리에 어딘가에는 위치해 있어야 한다.) 모든 것이 메모리 어딘가에 위치해 있어야 한다. (함수 == 코드 섹션의 주소) 근데 각 개체마다 멤버 함수의 메모리가 잡혀 있을까? 아니다. 모든 개체는 함수 하나를 공유한다. 그 대신 각 멤버 함수는 컴파일..

템플릿의 장단점

템플릿의 장점템플릿이 다른 제네릭 프로그래밍보다 Type Safe하다.템플릿은 컴파일 타임에 받을 수 있는 모든 타입을 오버로딩한다.따라서 템플릿은 제대로 사용하기만 한다면 타입 안전성을 보장한다.하지만 다른 제네릭 프로그래밍은void*로 변환하여 값을 받아오기 때문에,위험성이 따른다.템플릿의 단점템플릿은 동형(homogenous)데이터 구조만 지원한다.데이터 구조마다 한가지 타입으로 된 객체만 저장할 수 있다.앞서 말했듯 템플릿은 동형 데이터 구조만을 지원하며,이를 위해 컴파일 타임에 받아올 모든 타입을 오버로딩하기 때문에,최종 바이너리 코드의 크기가 커지는코드 비대 현상이 발생한다.각 템플릿 인스턴스에 고도로 특화된 코드는그보다 느리지만 범용적인 코드보다 길어지는 경향이 있다.+템플릿과 상속 둘 중 ..

범용 데이터 구조

템플릿으로 범용 데이터 구조와 알고리즘 구현 템플릿을 이용하면 범용 구조체 타입 또는 클래스 형태를 생성할 수 있다. 가능하면 데이터 구조와 알고리즘을 프로그램에 특화된 방식으로 만들지 말고, 최대한 범용적으로 만든다. 템플릿이 아닌 범용 데이터 구조 구현 방법 템플릿 말고 다른 범용 데이터 구조는 얼마든지 만들 수 있다. 좀 구식이긴 하지만 C, C++의 void*가 해당 예시이다. 하지만 이 방법은 타입 세이프(안정적)하지 않다. C++17부터는 void*와 템플릿을 사용하지 않고 std::any 클래스를 사용하는 방법이 있다. 객체 타입이 무엇이든 any클래스에 저장할 수 있다. std::any 내부에서 void*를 사용하지만, 본래 타입(자료형)을 저장해두기 때문에 안정성을 보장한다. 템플릿을 사..

OOP - 상속

상속의 특징다른 클래스의 특성들을 내려 받는다. Base Class 부모 클래스 Derived Class 자식 클래스 파생 클래스의 개체는 다음의 것들을 가진다.베이스 클래스의 멤버 변수베이스 클래스이 멤버 메서드자신의 생성자와 소멸자 파생 클래스는 멤버 변수 및 메서드 추가가 가능하다. 상속은 is a관계를 가진다. 상속의 이점상속을 쓰는 가장 간편한 이유는 부모 클래스가 올바르게 제대로 작동하고 있다는 가정 하에, 자식 클래스가 부모 객체가 가진 변수들은 다 부모에게 넘긴다. 그렇게 되면 자식 클래스는 자신의 변수들만 제대로 관리하면 된다. 예시 코드)Cat::Cat(int age, const char* name) : Animal(age) { size_t size = strlen(name)+1; mN..

연산자 오버로딩을 남용하는 것

남용하여 나만의 의미로 만들면협업의 효율성이 떨어질 수 있다.자유도가 높은 언어일 수록애매하게 쓰지 않도록 함수로 만드는 것이 좋다. (ex 자바처럼)가령 다음과 같이벡터 *= 벡터 의 코드와 같은 경우에연산자 오버로딩을 사용했다면 해당 경우가 벡터 곱샘이 외적인지 내적인지 모호성을 띄게 된다.이를 함수로 명확히 이름을 통해 알 수 있도록 코드를 제작하여,dotproduct 인지 crossproduct 인지 명확한 이름을 사용하여 함수를 짠다면가독성도 높고, 해당 코드에 대한 의미가 명확해진다.대입 연산자와 복사 생성자의 유사성복사 생성자와 대입 연산자는 거의 비슷하지만차이점은대입 연산자는 메모리를 해제해 줄 필요가 있을 수 있으며,대입 연산자는 이미 만들어 진 객체를 쓰고복사 생성자는 방금 생성된 객체..

연산자 오버로딩과 const

const를 쓰는 이유는?멤버 변수의 값이 바뀌는 것을 방지하기 위해서최대한 많은 곳에 const를 붙일 것지역 변수에 까지도 붙일 것모든 회사가 이 코딩 표준을 따르지는 않는다. Vectro operater + (const Vector& rhs) const; const &를 사용하는 이유는?불필요한 개체의 사본이 생기는 것을 방지하기 위해서이다.멤버 변수가 바뀌는 것 역시 방지하기 위해서이다.어디에 const를 넣고 안넣고는 곰곰히 생각하면어디에 const를 넣어야 할 지 알 수 있다.생각보다 연산자 오버로딩에서 const는 생각보다 잘못쓸 가능성이 있다.왜냐하면 연산자 오버로딩을 짤 일이 별로 없기 때문이다. 잘못 사용하는 코드는 다음 예시와 같다.// 잘못된 코드의 예시std::ostream& op..

C++ 함수 오버로딩과 C언어의 _Generic

C++ 함수 오버로딩은 C++만의 것이라고 보긴 어렵다. C에서도 함수 오버로딩과 비슷한 기능이 있다. _Generic 키워드를 사용하여 컴파일 시간에 인수의 형식을 기반으로 식을 선택하는 코드를 작성하면 된다. 인수의 형식을 호출할 함수가 선택되는 C++의 오버로딩과 유사하다. 여기서는 인수의 형식을 기반으로 평가할 식이 선택된다. 예를 들어 _Generic(42, int : "integer", char : "character", default : "unknown");은 42의 형식을 평가하고 목록에서 일치하는 형식 int를 검색한다. 이 형식을 찾아 "integer"를 반환한다. generic-selection: ( , ) _Generic assignment-expressionassoc-list as..