공부/C || C++ 43

const 멤버 함수의 리턴 타입을 레퍼런스로 할 수 없는 이유/ const 멤버함수 내부에서 const가 아닌 멤버 함수를 호출할 수 없다

위의 GetBar 함수같은 표현은 허용되지 않는다. 그 이유는 stackoverflow에서 쉽게 찾을 수 있다. 요약하자면 레퍼런스를 리턴하면 클래스의 내부 상태(여기선 Bar 멤버 변수)를 바꾸지 않는 다는 것(const)을 보장할 수 없기 때문이다. 따라서 const를 빼던가 레퍼런스(&)를 리턴 타입에서 빼줘야 한다 여담이지만 const 멤버 함수 내부에서는 const 멤버 함수가 아닌 다른 함수를 호출할 수 없다. Reference https://stackoverflow.com/questions/4957025/const-methods-that-return-references/4957167 Const Methods that Return References class Foo { int Bar; pub..

공부/C || C++ 2021.11.12

C++ const가 붙는 위치에 따른 의미변화

포인터 변수의 const는 붙는 위치에 따라 의미가 다르다. 아래 글은 Reference에 쓰여져 있는 포스팅이 정리가 잘 되어 있어서 인용했다. int const * p; // 1 int * const p; // 2 int const * const p; // 3 const int * p; // 4 p = (int *)0x1000; // 가 p++; // 나 *p = 100; // 다 a = *p; // 라 const는 바로 앞의 키워드에 대해 상수화가 이루어진다고 보면 된다. 단 예외적으로 4번은 앞에 아무 키워드도 없으니 뒤에 있는 키워드에 대해 상수화를 시킨다. 그래서 1 -> 값에 대한 상수화 2 -> 포인터에 대한 상수화 3 -> 값, 포인터 모두에 대한 상수화 4 -> 값에 대한 상수화 그래서..

공부/C || C++ 2021.09.01

C++ 변환 연산자(Conversion Operator)

C++ 클래스에서는 변환 연산자(Conversion operator)라는 특이한 함수를 연산자 오버로딩할 수 있다. 예를 들어서 아래와 같이 CSharedPtr을 구현한 상태라고 생각해보자. #pragma once template class CSharedPtr { public: CSharedPtr(): m_Ptr(nullptr) { } CSharedPtr(T* Ptr) { m_Ptr = Ptr; if (m_Ptr) m_Ptr->AddRef(); } CSharedPtr(const CSharedPtr& Ptr) { m_Ptr = Ptr.m_Ptr; if (m_Ptr) m_Ptr->AddRef(); } ~CSharedPtr() { if (m_Ptr) m_Ptr->Release(); } private: T* m..

공부/C || C++ 2021.08.28

C++ vector의 resize vs reserve

vector에는 resize 함수와 reserve 함수가 있다. 언뜻 보기에 같은 동작을 하는 것 처럼 보이지만 다른 동작을 하는 함수다. void resize (size_type n, value_type val = value_type()); vector는 미리 할당된 공간에 element를 채우면서, 할당된 공간이 모두 차면, 2배 크기의 새로운 공간을 할당해서 element를 옮겨준다. 여기서 말하는 '미리 할당된 공간'을 capacity라고 하며, 'element가 실제로 들어있는 공간'을 size라고 부른다. 예를 들어서 벡터에 미리 할당된 공간이 4개라고 가정하고, 1,2,3 각각을 vector에 push_back했다고 가정해보자. vector vec; vec.push_back(1); vec.p..

공부/C || C++ 2021.08.25

C++ 오버라이딩시 반환 타입을 자식 클래스 타입으로 하면 반환 타입이 다르게 오버라이딩 된다

일반적으로 부모클래스에 정의된 멤버 함수를 자식 클래스에서 재정의하는 것을 오버라이딩(overriding)이라고 하는데, 이 오버라이딩은 함수 이름, 매개 변수, 반환 타입까지 같아야 한다고 알고 있을 것이다. 하지만 아래 경우처럼 부모 클래스에서 정의한 함수를 자식 클래스에서 오버라이딩할 때, 그 오버라이딩 하려는 함수의 타입을 자식 클래스 타입으로 하면 오버라이딩 함수의 타입을 다르게 해도 오버라이딩이 가능하다(근본적으로는 타입이 다르다라고 할 순 없다. 이 경우 covariant한 타입이라고 표현을 하더라) class CParent { public: CParent(); virtual ~CParent(); CParent(const CParent& Parent); virtual CParent* Clon..

공부/C || C++ 2021.08.21

C++ return new(*this); 는 복사 생성자를 호출한다

프로젝트를 진행중에 prototype을 clone하는 코드를 작성해야 했는데 다음과 같은 방식으로 작성한 코드를 보았고 이게 과연 복사 생성자를 호출할지, 그냥 생성자를 호출할 지 궁금했다. CClass* CClass::Clone() { return new CClass(*this); } 내가 아는 복사 생성자의 호출 시기는 객체를 인자로 넘길 때 reference 형태가 아닌 value 형태로 넘길 때 객체를 값으로 반환할 때 객체를 생성과 동시에 기존에 존재하는 객체로 초기화 할 때 이렇게 3가지 인데, 저 3가지중에 어디에 해당되는지 확신이 없었다. 1, 2번은 당연히 아니고 3번이 의심돼서 아래와 같은 코드를 작성하고 직접 확인해보았다. //CClass.h class CClass { public: ..

공부/C || C++ 2021.08.17

C/C++ 파일 입출력

C 스타일 파일 입출력 errno_t fopen_s( FILE** pFile, const char *filename, const char *mode ); return : 성공 시 0을 리턴하고, 에러 발생 시 errno_t타입의 0이 아닌 값을 리턴 pFile : FILE타입(파일 스트림)의 이중 포인터 filename : 파일 이름. 파일 이름만 쓰고, visual studio에서 빌드 하면 프로젝트 파일이 있는 곳에 파일을 만든다 mode r : 파일 읽어오기 w : 파일 쓰기(만들기) a : 파일에 접근하여 이어 쓰기 r+ : 파일이 존재하면 해당 파일을 읽고 쓰기 가능하게 연다. 파일이 없으면 에러를 반환 w+ : 파일이 존재하면 해당 파일에 읽고 쓰기 가능하게 연다. 파일이 없으면 새로 만든다 ..

공부/C || C++ 2021.08.14

C/C++ 함수 포인터를 반환하는 함수

Linux에서 제공되는 signal 함수(시그널 등록 함수라고 표현하기도 함)를 보면 특이한 형태를 보인다. 함수 포인터는 알고 있었지만, '함수 포인터를 리턴하는 함수'는 처음 보는 것 같아서 따로 정리하려고 한다. 복잡한 것은 아니고 정해진 syntax가 있기 때문에 규칙만 알면 어렵지 않다. 함수 포인터를 리턴하는 함수를 선언하려면 아래와 같은 규칙을 따르면 된다. 함수포인터반환값자료형 (*함수이름(매개변수자료형 매개변수))(함수포인터매개변수자료형1, 함수포인터매개변수자료형2) { } signal.h에 포함된 signal함수를 보자 void (*signal( int sig, void (*handler) (int))) (int); 그렇다면 위의 함수는 아래와 같은 의미이다. 함수 이름은 signal이..

공부/C || C++ 2021.08.06