C++ friend
·
C++/Class
friend 클래스 내부에다가 friend 키워드 다음에 다른 클래스나 함수를 선언하면, 해당 클래스나 함수에서 private 멤버에 접근할 수 있다. 예제 간단한 예제 #include class A { int value_ = 1; friend void doSomething(A& a); }; void doSomething(A& a) { std::cout
C++ 정적 멤버 함수 (Static Member Function)
·
C++/Class
정적 멤버 함수 (Static Member Function) 클래스의 멤버 함수들은 한 번만 정의하고, this를 통해 인스턴스의 주소를 포함해서 전달한다고 했다. 인스턴스 없이 범위 지정 연산자로 바로 멤버 함수를 사용하고자 할 때, 굳이 static을 붙여야 동작할 수 있는건가 싶어서 간단한 예제를 만들어 보았다. #include class Something { static int s_value_; public: int getValue() { return s_value_; } }; int Something::s_value_ = 1; int main() { using namespace std; cout
C++ 정적 멤버 변수 (Static Member Variable)
·
C++/Class
정적 멤버 변수 (Static Member Variable) 클래스 내부에 static 변수를 정의할 때는 직접 초기화할 수 없다. 중복 선언 문제인 것 같다. 생성자에서도 초기화할 수 없다. Inner Class를 사용해서 우회하여 초기화할 수는 있다. 예제 static이 아닌 기본 예제 #include class Something { public: int value_ = 1; }; int main() { using namespace std; Something st1; Something st2; st1.value_ = 2; cout
C++ static (Class)
·
C++/Class
static 정적 멤버 변수 (Static Member Variable) 정적 멤버 함수 (Static Member Function)
C++ 체이닝(Chaining)
·
C++/Class
체이닝(Chaining) 함수의 반환 값을 해당 인스턴스의 레퍼런스로 전달하여, 연속해서 함수를 사용할 수 있도록 하는 기법이다. 아래와 같이 함수를 하나씩 작성하면 귀찮다. #include class Calc { int value_; public: Calc(const int &value_in) : value_{value_in} {} void add(int value) { value_ += value; } void sub(int value) { value_ -= value; } void mul(int value) { value_ *= value; } void print() { std::cout
C++ this
·
C++/Class
this 인스턴스 객체의 주소를 가리킨다. 예제 #include class Simple { int id_; public: Simple(const int& id_in) { setID(id_in); std::cout
C++ 소멸자 (Destructor)
·
C++/Class
소멸자 (Destructor) 인스턴스가 메모리에서 해제될 때 내부에서 호출되는 함수 메모리 누수를 방지할 때 필수적이다. #include class Simple { int num_; public: Simple(const int& num_in) : num_{num_in} { std::cout
C++ 변환 생성자(Converting Constructor)
·
C++/Class
변환 생성자(Converting Constructor) explicit 키워드가 없는 생성자는 묵시적으로 형변환을 허용한다. 변환이 가능한 경우는 해당 인자를 생성자에 인자로 주었을 때 유효한 경우이다. #include #include class Fraction { int numerator_; int denominator_; public: Fraction(int num = 0, int den = 1) : numerator_(num), denominator_(den) { std::cout
C++ delete
·
C++/Syntax
delete 함수를 사용하지 못하도록 막는 역할을 하는 키워드이다. #include #include class Fraction { int numerator_; int denominator_; public: Fraction(char) = delete; explicit Fraction(int num = 0, int den = 1) : numerator_(num), denominator_(den) { std::cout
C++ 깊은 복사(Deep Copy)
·
C++/Syntax
깊은 복사(Deep Copy) 하위 항목을 모두 복사하는 것 #include #include class MyString { char* data_ = nullptr; int len_ = 0; public: MyString(const char* source = "") { assert(source); len_ = std::strlen(source) + 1; data_ = new char[len_]; for (int i = 0; i < len_; ++i) data_[i] = source[i]; data_[len_ - 1] = &#39;\0&#39;; } ~MyString() { delete[] data_; } MyString(const MyString& source) { std::cout
C++ 얕은 복사(Shallow Copy)
·
C++/Syntax
얕은 복사(Shallow Copy) 얕은 복사는 허상 포인터(Dangling pointer) 문제를 일으킬 수 있다. #include #include class MyString { char* data_ = nullptr; int len_ = 0; public: MyString(const char* source = "") { assert(source); len_ = std::strlen(source) + 1; data_ = new char[len_]; for (int i = 0; i < len_; ++i) data_[i] = source[i]; data_[len_ - 1] = &#39;\0&#39;; } ~MyString() { delete[] data_; } char*& getString() { retu..
C++ 복사 생성자(Copy Constructor)
·
C++/Class
복사 생성자(Copy Constructor) 보안이 중요한 경우 복사 생성자를 private로 정의하여 복사를 방지하기도 한다. 기본 복사 생성자는 얕은 복사이므로 주의하자. 이를 방지하기 위해 깊은 복사를 구현해야 하는데, 시간적 여유가 없을 경우 임시로 delete를 통해 구현하기도 한다. copy initialization, direct initialization, uniform initialization 모두 복사 생성자를 호출한다. #include #include class Fraction { int numerator_; int denominator_; public: Fraction(int num = 0, int den = 1) : numerator_(num), denominator_(den) ..
C++ 위임 생성자 (Delegating Constructor)
·
C++/Class
위임 생성자 (Delegating Constructor) C++11 생성자에서 직접 생성하지 않고, 이미 구현된 생성자를 호출해서 대신 생성하도록 하는 것이다. 기본 예제 다음 예제에서는 st2를 생성할 때 id_, name_ 멤버 변수를 초기화 리스트로 초기화하고있다. #include using namespace std; class Student { int id_; string name_; public: Student(const string& name_in) : id_{0}, name_{name_in} { print(); } Student(const int& id_in, const string& name_in) : id_{id_in}, name_{name_in} { print(); } void prin..
C++ 멤버 초기화 리스트 (Member Initializer Lists)
·
C++/Class
멤버 초기화 리스트 (Member Initializer Lists) 생성자를 만들 때 멤버들을 초기화해주는 기능 C++11부터 배열도 이 방식으로 초기화 가능하다고 한다. #include class Something { int i_; double d_; char c_; public: Something() : i_{ 1 }, d_{ 3.14 }, c_{ &#39;a&#39; } {} }; int main() { Something a; } 기본 값 적용 우선순위가 헷갈릴 때 #include class Something { int i_ = 100; double d_ = 100.0; char c_ = &#39;F&#39;; public: Something() : i_{ 1 }, d_{ 3.14 }, c_{ &#..
C++ 생성자 (Constructor)
·
C++/Class
생성자 (Constructor) 인스턴스가 처음 생성될 때 호출되는 함수 멤버 변수부터 생성하고 그 다음 호출된다. 멤버 중에 클래스가 있을 경우 해당 클래스의 생성자부터 호출된다. #include class Second { public: Second() { std::cout
C++ 접근 지정자 (Access Specifier)
·
C++/Class
접근 지정자 (Access Specifier) 종류 public : 어디서든 접근 가능하다. private : 해당 클래스와 friend 클래스만 접근 가능하다. protected : private 특성을 기본으로, 상속받은 자식 클래스도 접근 가능하다. 명시하지 않는 경우, 기본 값은 private이다. private이어도 같은 클래스면 다른 인스턴스의 멤버를 사용할 수 있다. class Date { int year_; int month_; int day_; void copyFrom(const Date& original) { year_ = original.year_; month_ = original.month_; day_ = original.day_; } }; public 멤버 변수들에 대해 unifo..
C++ Class
·
C++/Class
Class struct vs class c++에서의 구조체도 멤버 함수를 가질 수 있다. _단순한 기능_의 경우 struct를 사용해도 무방하다. class를 사용하는 이유는 다양한 객체지향 프로그래밍 기법들을 적용하기 위함이다. Access Specifier (public, private, protected 등) 접근 지정자 (Access Specifier) 생성자 (Constructor) 소멸자 (Destructor) this const static friend 익명 객체 (Anonymous Class) Nested Types 실행 시간 측정 (Run Time Measurement) 참고 따라하며 배우는 C++
따라하며 배우는 C++ 8장
·
C++/TBC++
따라하며 배우는 C++ 8장 Class 참고 따라하며 배우는 C++
C++ assert
·
C++/Library
assert 라이브러리 assert Debug 모드에서만 런타임에 작동한다. VS의 전처리기 설정에 매크로가 설정되어있다. Debug 모드에서는 _DEBUG Release 모드에서는 NDEBUG 내부 조건이 거짓이면 Debug Error를 발생시킨다. #include int main() { assert(false); } 최대한 나눠서 쓰는게 디버깅하기에 좋다. static assert 컴파일 타임에 작동한다. Release 모드에서도 작동한다. 에러 문구를 넣어야 한다. #include int main() { const int x = 5; //const int x = 4; // 컴파일 안됨 static_assert(x == 5, "x should be 5"); } 릴리즈 모드에선 작동되지 않는다면, 차라..
C++ vector
·
C++/Library
vector 라이브러리 기본 예제 push_back 함수로 벡터의 맨 뒤에 원소를 추가할 수 있다. foreach로 반복문을 작성할 수 있다. (iterator가 존재하기 때문에 사용 가능) #include #include int main() { using namespace std; vector vec; for (int i = 0; i < 10; ++i) vec.push_back(i); for (auto& e : vec) cout
C++ 함수 포인터 (Function Pointer)
·
C++/Syntax
함수 포인터 (Function Pointer) 기본 예제 배열에서 짝수, 홀수를 각각 출력하는 예제 간단한 버전 #include #include using namespace std; void printNumbers(const array& arr, \ bool print_even) { for (auto e : arr) if ((print_even && e % 2 == 0) || \ (!print_even && e % 2 == 1)) cout
C++ 인라인 함수 (Inline Function)
·
C++/Syntax
인라인 함수 (Inline Function) 함수 반환 값 정의 앞에 inline 키워드를 붙여주면 된다. 컴파일러가 인라인으로 넣을지 결정한다. inline 키워드를 넣지 않아도 인라인 함수로 작동시킬 때도 있고, 키워드를 넣어도 인라인 함수로 작동하지 않는 경우가 있다.
C++ tuple
·
C++/Library
tuple C++11 라이브러리 #include #include std::tuple getTuple() { return (std::make_tuple(10, 3.14)); } int main() { using namespace std; tuple my_tp = getTuple(); cout
따라하며 배우는 C++ 7장
·
C++/TBC++
따라하며 배우는 C++ 7장 Call by Reference std::tuple 인라인 함수 (Inline Function) 함수 포인터 (Function Pointer) std::vector assert 참고 따라하며 배우는 C++
C++ 레퍼런스 (Reference, 참조)
·
C++/Syntax
레퍼런스 (Reference, 참조) 함수의 인자로 const int & 형태를 자주 사용하는 이유 레퍼런스 : 불필요한 복사가 발생하지 않아서 성능 상 이점을 가진다. const : rvalue도 인자로 넘길 수 있어서 확장성이 좋아진다. Call by Reference 포인터를 레퍼런스로 전달하는 방법 #include void foo(int*& ptr) { std::cout
C++ Stack Size
·
C++/Syntax
Stack Size VS에서는 아래와 같은 경우 경고를 띄운다. int main() { using namespace std; int arr[10000]; (void)arr; } 경고 내용 Warning C6262 Function uses &#39;40000&#39; bytes of stack: exceeds /analyze:stacksize &#39;16384&#39;. Consider moving some data to heap. 찾아보니 VS의 기본 스택 프레임 사이즈가 16KB로 설정되어있었고, 변경 가능하다. 스택 사이즈를 제한하는 이유는 쓰레드 개수의 확보를 위해서, 또 스택 오버플로우를 방지하기 위해서라고 한다. OS에 따라 스택 오버플로우 발생 시 자동으로 스택 사이즈를 늘리는 방식도 있다고..
C++ 문자열 (string)
·
C++/Syntax
문자열 (string) text segment #include int main() { using namespace std; const char* name = "Jack jack"; const char* name2 = "Jack jack"; cout
C++ nullptr_t
·
C++/Syntax
nullptr_t C++11 C언어에서 사용되지는 않으나, 라이브러리에 존재하는 자료형이다. #include #include void f(int*) { std::cout
C++ array
·
C++/Library
std::array C++11 size(), begin(), end(), at() 등의 함수 사용 가능 at()으로 접근하는 것은 arr[1] 처럼 직접 주소로 접근하는 것보다 느리지만 조금 더 안전하다. at() 함수는 std::exception을 통해 예외 처리가 되어있다. algorithm 라이브러리의 sort 함수 사용 가능
C++ typeinfo
·
C++/Library
데이터 타입 확인 라이브러리의 typeid().name()을 사용한다. cout