본문 바로가기

C++12

[C++] 포인터와 참조자, Call by Value와 Call by Reference 1. 포인터 메모리는 연속적인 주소를 가지며 모든 변수는 메모리 상에 존재한다. C++를 사용해 변수를 선언하면 운영체제는 런타임에 적당한 위치의 메모리를 할당해서 내어주게 된다. 포인터란 이렇게 값이 아닌 주소를 저장하는 변수를 의미한다. 포인터를 사용하면 동적으로 결정된 메모리의 주소를 직접 다룰 수 있으며 때로는 임의의 메모리에 접근할 수도 있다. 프로그래머가 직접 주소를 다루게 되면 프로그램 작성의 복잡도가 증가하고 실수가 늘어나지만, 그만큼 프로그램을 더 효율적으로 작성하는데 도움을 주는 경우가 많다. 2. 주소 연산자(&)와 역참조 연산자(*) int value = 3; //*를 변수를 선언할 때 타입 뒤(혹은 변수명 앞)에 붙여서 주소 타입의 변수로 지정 int *ptr = &value; /.. 2021. 9. 8.
Effective C++ (51) ~ (55) 51) new 및 delete를 작성할 때 따라야 할 기존의 관례를 잘 알아두자 operator new는 다음과 같은 요구사항을 만족해야 한다. 반환 값이 제대로 되어있어야 함 가용 메모리가 부족할 경우에는 new 처리자 함수를 호출해야 한다 크기가 없는 메모리 요청에 대한 대비책을 갖춰두어야 한다. 기본 형태의 new가 가려지면 안된다. 위 조건을 만족하는 operator new를 의사 코드로 만들면 다음과 같다. void * operator new(std::size_t size) throw(std::bad_alloc) { using namespace std; if (size==0) { size = 1; } while(true){ size 바이트 할당 if(할당 성공시) return 할당된 메모리에 대.. 2021. 8. 29.
Effective C++ (46) ~ (50) 46) 타입 변환이 바람직할 경우에는 비멤버 함수를 클래스 템플릿 안에 정의해 두자. 항목 24에서 모든 매개변수에 대해서 암시적 타입 변환이 되도록 만들기 위해서는 비멤버 함수밖에 방법이 없다는 이야기를 했었다. 이것을 템플릿으로 확장해보자. template class Rational { public: Rational(const T& numerator = 0, const T& denominator = 1); // 매개변수가 참조자로 전달되는 이유는 항목 20 const T numerator() const; const T denominator() const; }; template const Rational operator*(const Rational& lhs, const Rational& rhs) { ... 2021. 8. 28.
Effective C++ (41) ~ (45) 7. 템플릿과 일반화 프로그래밍 41) 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터 클래스와 템플릿은 모두 인터페이스와 다형성을 지원한다. 명시적 인터페이스 : 소스 코드에 명시적으로 드러나는 인터페이스 런타임 다형성 : 실제 호출이 동적 타입 기반으로 런타임에 결정되는 경우 암시적 인터페이스 : 제대로 컴파일 되기 위해 필요한 ‘유효한’ 표현식 컴파일 타임 다형성 : 컴파일 도중 인스턴스화가 진행되는 함수 템플릿에 어떤 템플릿 매개 변수가 들어가느냐에 따라 호출되는 함수가 달라지는 경우 클래스의 경우 인터페이스는 명시적이고 함수의 시그니처를 중심으로 구성되어 있다. 다형성은 런타임에 가상함수를 통해 나타난다. 템플릿 매개변수의 경우 인터페이스는 암시적이고 유효 표현식을 기반으.. 2021. 8. 26.
Effective C++ (36) ~ (40) 36) 상속받은 비가상 함수를 파생 클래스에서 재정의하는 것은 절대 금물! 비가상 함수는 정적 바인딩, 가상 함수는 동적 바인딩으로 이루어진다. 만약 비 가상 함수를 재정의하고 호출한다면 호출하는 객체의 타입에따라 동작이 달라진다. 따라서 상속받은 비가상 함수는 절대로 재정의하지 말자. 37) 어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 재정의하지 말자 기본값을 정의해둔 가상 함수의 매개변수는 절대로 상속하면서 파생 클래스에서 값이 달라지거나 하지 않도록 주의하자. 가상 함수 자체는 동적으로 바인딩되어 있지만 기본 매개변수는 정적으로 바인딩되어있다. 이는 런타임 효율을 높이기 위해서이다. 따라서 파생 클래스에 정의된 가상 함수를 사용하면서 매개 변수는 기본 클래스의 매개변수를 사용하게 될 수.. 2021. 8. 25.
Effective C++ (31) ~ (35) 31) 파일 사이의 의존성을 최대로 줄이자 #include는 헤더 파일들 사이에 컴파일 의존성을 만든다. 보통은 전방 선언으로 이러한 문제를 해결한다. 이 때 표준 라이브러리들은 전방 선언을 하지 않는다. precompiled header를 쓰는 환경이라면 더더욱 그럴 필요가 없다. 전방 선언시 pimpl 관용구를 통해 인터페이스와 구현을 분리하면, 구현을 수정했을 때 해당 클래스를 사용하는 다른 부분은 컴파일을 다시 할 필요가 없게 된다. 아래 foo 클래스와 같이 pimpl 관용구를 사용하는 클래스를 핸들 클래스라고 한다. class fooImpl; class foo{ private: std::shared_ptr pImpl; } 컴파일 의존성을 최소화하는 전략은 다음과 같다. 객체 참조자나 포인터로 .. 2021. 8. 24.
반응형