C++ 16

우측값 참조와 이동연산

우측값 참조란?우측값 참조는 이름처럼 우측값을 참조하는 자료형입니다. r-value reference라고도 합니다.lvalue만을 참조할 수 있던 일반적인 참조형과는 다릅니다.일반 참조형은 &기호를 쓰지만, 우측값 참조는 &&를 씁니다.아래 코드를 봐주세요.int main(){ int i = 10; int& iRef = i; //lvalue만 참조 가능 //int& iRef = 10; //컴파일 에러 : 비const 참조에 대한 초기값은 lvalue여야 함 int&& rRef = 11;// rvalue만 참조 가능 //int&& rRef = i;//컴파일 에러 : rvalue 참조를 lvalue에 바인딩할 수 없습니다. const int& cRef = i; //lvalu..

C++ 2024.05.02

RTTI

이번 글은 C++의 virtual 함수의 동작에 대해 이해하고 있으면 더욱 읽기 좋습니다.  모르시는 분은 아래 글을 읽고 보시길 추천합니다.https://ddukddaksudal.tistory.com/147RTTI란?RTTI는 'Run Time Type Information'의 약자입니다. 한국말로는 '실행시간 형식 정보'가 되겠네요.말 그대로 런 타임에 어떤 객체의 타입(형식)을 알 수 있도록 하는 기능입니다.그렇다면 왜 런타임에 객체의 타입을 알아야 할까요? 필요성런타임에 객체의 타입을 알아야하는 상황을 만들어 보겠습니다. class Mover{public: virtual ~Mover() {}};class Walker : public Mover{public: void Walk() { cout 위 코..

C++ 2024.04.27

이름 숨김

이름 숨김이란, 어떤 멤버 A가 있을 때, 중첩된 선언 영역 혹은 파생 클래스에서 같은 이름의 멤버를 선언할 경우, 멤버 A가 무시되는 규칙입니다. https://www.ibm.com/docs/en/i/7.5?topic=scope-name-hiding-c-only Name hiding (C++ only) If a class name or enumeration name is in scope and not hidden, it is visible. A class name or enumeration name can be hidden by an explicit declaration of that same name — as an object, function, or enumerator — in a nested de..

C++ 2024.04.15

가상함수

다형성 다형성이란 하나의 객체가 여러 타입을 가질 수 있는 것을 말합니다. 반대로 하나의 타입이 여러 타입의 객체를 참조할 수 있는 것도 다형성입니다. 다형성은 상속과 오버라이딩을 통해 구현될 수 있습니다. 오버라이딩 클래스의 멤버 함수는 파생 클래스에서 오버라이딩 될 수 있습니다. 즉, 같은 모습의 함수가 여러 개 존재할 수 있습니다. 같은 모습의 함수이지만, 여러 개의 구현이 존재할 수 있습니다. 그런데, 똑같이 생긴 함수를 똑같은 형식으로 호출한다면, 자식과 부모 중 어떤 함수를 호출해야 할까요? class Parent { public: void Func() { m_i = 1; } int m_i; }; class Child : public Parent { public: void Func() { m_..

C++ 2024.04.12

헷갈리는 C++ 질문들

1. 멤버 객체 선언 시, 원하는 생성자를 호출하는 방법은? Initialize() 함수나 생성자의 블록 내에서 대입 생성 시 생성자가 두 번 호출되어 비효율적이지만, 아래와 같이 생성자의 멤버 이니셜라이저를 사용하거나, 멤버 변수 선언 옆에 대입 생성자를 호출하면 생성자가 한 번만 호출된다. class A { public: A(){} A(int _i){} } class B { public: B() : a(10){} // 이니셜라이저 사용 public: A a = A(10);// 혹은 대입 생성 } 2. 부모에서 멤버로 선언한 객체의 생성을 원하는 생성자로 하는 방법은? 생성자 혹은 다른 함수에서 m_A = A(10); 와 같이 따로 생성해줄 수 있다. 그러나 이 방법은 이미 생성된 m_A에 또 다시 A..

C++ 2024.04.12

Casting (Static, Dynamic, Reinterpret )

C++의 캐스터는 static_cast, dynamic_cast, reinterpret_cast 세 가지 종류가 있다. 각 캐스터는 약간씩 다른 방식으로 동작하고, 제약사항도 다르다. 따라서 상황마다 적절한 캐스터를 사용해 주어야 한다. 그럼 각 캐스터의 특징, 사용하면 좋은 상황 등을 알아보자. 미리 3줄요약: static_cast : 기초 유도, 기본 자료형 캐스팅 dynamic_cast: 기본적으로 유도 - > 기초 캐스팅. virtual함수 있으면 유도 기초 캐스팅. 런타임에 안정성 검사. reinterpret_cast : 포인터, 포인터 관련 형 변환 모두 허용. static_cast static_cast는 기본 자료형의 캐스팅, 그리고 기초 클래스와 유도 클래스의 포인터 ..

C++ 2023.03.28

스마트 포인터

스마트 포인터란 스마트 포인터란 포인터의 부족했던 기능적인 면들을 보완한 것이다. 스마트 포인터는 shared_ptr, weak_ptr, unique_ptr 세 종류가 있다. 그럼 포인터의 어떤 부족한 면을 보완했는지 알아보자. shared_ptr shared_ptr은 여러 포인터 변수가 하나의 객체를 참조하고 있는 상황에서 객체가 delete 되었을 때, 그 객체를 참조하고 있던 포인터 변수들은 이를 모르고 계속 참조하고 있는 상황을 해결하기 위한 스마트 포인터이다. 작동 방식은 기존 포인터를 포인터와 그 포인터가 참조하고 있는 객체를 몇 개의 포인터 변수가 참조하고 있는지 갯수를 가지고 있는 변수를 담은 클래스로 관리하는 것이다. 여기서 중요한 것은 몇 개의 포인터가 참조하고 있는지를 담은 변수를 컨..

C++ 2022.03.29

순환문제

순환문제란 shared_ptr을 서로 교차해서 참조하는 경우에 그 포인터를 해제시켜도 해제되지 않고 메모리에 계속 남아있는 현상을 말한다. 아래 상황을 보자. (참고로 코드를 직접 실행해 보지는 않았음 그냥 상황만 보셈) class Knight { sharerd_ptr _target; } void main() { sharerd_ptr k1 = make_shared(); sharerd_ptr k2 = make_shared(); k1._target = k2; k2._target = k1; k1 = nullptr; k2 = nullptr; } 위처럼 두 Knight 객체의 스마트 포인터가 서로를 참조하고 있을 때, k1과 k2가 서로의 Reference Count를 증가시키고 있다. 이 때 우리 생각대로라면 ..

C++ 2022.03.28

STL 컨테이너별 간략 특징 정리

C++ STL에는 여러 종류가 있다. 대표적으로 많이 사용하고 중요한 것들 위주로 알아보자. vector list deque(double-ended queue) 컨테이너 어댑터 queue priority queue stack 연관 컨테이너 정렬되는 연관 컨테이너 map set multiset multimap 정렬 안되는 연관 컨테이너 unordered set(hash set) unorderd map(hash map) vector 벡터는 배열을 기반으로 만들어졌다. 따라서 배열의 특징을 전부 가지고 있다. 그러나 그냥 배열은 그 크기가 고정적이라는 치명적인 단점이 있다. 그래서 벡터는 이 단점을 해결하기 위해 어떤 방식을 사용한다. 그 방식이란, 배열이 다 찼는데 삽입을 하면 원래 배열보다 더 큰 새로운 ..

C++ 2022.02.21

TLS(Thread Local Storage)

TLS란 쓰레드마다 가지고 있는 로컬 저장소 이다. 이러한 저장소가 필요한 이유를 알아보자. 여러 쓰레드가 힙에 저장된 특정 변수를 참조하는 상황을 생각해보자. 이러면 하나의 공유 변수를 참조하기 위해 여러 쓰레드가 경합을 벌이게 된다. 즉 하나의 쓰레드가 참조하고 있으면 다른 쓰레드는 기다려야 한다는 뜻이다. 하지만 이때 만약 쓰레드마다 자신의 저장공간이 있고 그 공간에 공유 변수를 가져다 놓고 연산을 한다면 경합으로 인한 성능 저하를 피할 수 있을 것이다. 스택과 다른 점 : 스택은 함수를 위한 저장소이다. 계속 할당됐다 해제됐다를 반복한다. TLS는 쓰레드마다 영구적으로 데이터를 보관하는 용도로 사용한다. 스택은 영구적으로 뭔가를 저장하기엔 안좋음. 예시 //_declspec(thread) int3..

C++ 2022.02.01