프로그래밍 언어 96

쓰레드 기본 사용법

멀티스레드 프로그래밍은 멀티프로세서가 장착된 컴퓨터 시스템에서 중요한 기법이다.멀티스레드 프로그래밍을 이용하면 시스템에 있는 여러 프로세서 유닛을병렬로 사용하는 프로그램을 작성할 수 있다.시스템에 프로세서 유닛이 장착되는 방식은 다양하다.독립적인 CPU 프로세서 칩이 여러 개 달려 있을 수 있고,한 프로세스 칩 안에 코어라 부르는 독립 CPU가 여러 개 있을 수 있고,또 어떤 시스템은 두 가지 방식이 혼합되기도 한다.이렇게 프로세스 유닛이 여러 개 달린 프로세서를 흔히 멀티코어 프로세서라 부른다.사실 이렇게 프로세서가 여러 개 달린 시스템이 나온지 꽤 오래되었지만이제는 서버부터 개인용 컴퓨터, 심지어 스마트폰에 이르기까지 거의 모든 시스템이멀티코어 프로세서를 사용한다.이처럼 멀티코어 프로세서가 보변화되었..

decltype과 템플릿

decltype의 개요decltype 형식 지정자는 지정된 식의 형식을 생성한다.즉 쉽게 말해 받아온 개체 타입을 그대로 개체를 생성해주는 키워드이다. decltype의 일반적 용례 템플릿decltype 형식 지정자는 auto 키워드와함께 템플릿 라이브러리를 작성하는 개발자에게 주로 유용하다. decltype 및 autoC++14에서는 후행 반환 형식 없이 decltype(auto)를 사용하여반환 형식이 템플릿 인수에 따라 달라지는함수 템플릿을 선언할 수 있다. C++11에서는 auto 키워드와 함께 후행 반환 형식에 대한decltype 형식 지정자를 사용하여 반환 형식이해당 템플릿 인수의 형식에 종속되는 함수 템플릿을 선언할 수 있다. 예를 들어, 함수 템플릿의 반환 형식이템플릿 인수의 형식에 종속되는..

STL의 vector, push_back()과 emplace_back()

push_back , emplace_back 둘의 공통점push_back , emplace_back은두 함수 모두 vector컨테이너가 주어졌을 때 한 칸을 늘리고 해당 값을 넣어주게 된다. 둘의 차이점그러나 내부적으로 동작하는 것은 조금 다른데, push_back의 경우push_back의 경우 메모리를 이동하거나 임시 객체를 이용하여임시객체가 생성되고 넣어준 뒤에 임시 객체가 삭제되는 호출이 있다.-> 복사의 개념 emplace_back의 경우대신 emplace_back은 받은 인수를 이용해 내부에서 생성자를 통한 객체 생성 후추가를 하기 때문에 임시 객체의 생성, 파괴가 없어서 push_back보다 효율적일 수 있다.-> 이동의 개념

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..