Object Oriented Programming(C++)60 전문가를 위한 C++ | Chapter 10 상속 활용하기(상) 10.1 상속을 이용한 클래스 구현 현실에 존재하는 대상은 대체로 계층 구조에 속한다. 프로그래밍을 할 때도 클래스를 수정하거나 다른 클래스를 바탕으로 새 클래스를 정의할 때 이러한 관계를 분명히 볼 수 있다. C++는 진정한 is-a 관계를 정의하는 기능을 기본으로 제공한다. 10.1.1 클래스 상속하기 C++에서 클래스를 정의할 때 컴파일러에 클래스를 상속(inherit), 파생(derive), 확장(extend)한다고 선언할 수 있다. 이때 원본 클래스를 부모 클래스(베이스 클래스(base class) 또는 슈퍼 클래스(super-class))라고 부른다. 그러면 원본 클래스를 확장한 자식 클래스(파생 클래스(derived class) 또는 서브 클래스(sub-class))는 부모 클래스와 다른 부.. 2022. 1. 30. 전문가를 위한 C++ | Chapter 07 메모리 관리(하) 7.3 로우 레벨 메모리 연산 특정 애플리케이션이나 레거시 코드에서 로우 레벨 메모리를 다뤄야 할 때가 있다. 메모리를 저수준으로 관리하는 테크닉을 알아두면 여러모로 도움이 된다. 7.3.1 포인터 연산 C++ 컴파일러는 포인터 연산을 수행할 때 포인터에 선언된 타입을 이용한다. 예를 들어 다음과 같이 int 타입의 힙 배열을 선언한 경우를 살펴보자. 포인터 연산의 강점은 myArray + 2와 같이 표현식으로 포인터를 표현하고, 이를 이용해서 더 작은 정수 배열을 표현할 수 있다는 데 있다. int* myArray = new int[8]; myArray[2] = 10; *(myArray + 2) = 10; /* 포인터 연산으로 역참조합니다. */ 다음과 같이 와이드 문자열(wide string)을 인수.. 2022. 1. 29. Effective C++ | 항목 17 new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자 항목 17 new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자 17.1 스마트 포인터를 인자로 받는 함수 처리 우선순위를 알려주는 함수가 하나 있고, 동적으로 할당한 Widget 객체를 우선순위에 따라 처리하는 함수가 하나 있다고 가정해보자. 이렇게 만들어진 processWidget 함수를 다음과 같이 호출하면 자원을 흘릴 가능성이 있다. int priority(); void processWidget(std::shared_ptr pw, int prior); processWidget(std::shared_ptr(new Widget()), priority()); /* 자원이 누출될 수 있습니다.*/ 컴파일러는 processWidget 호출 코드를 만들기 전에 우선 이 함수의 매.. 2022. 1. 25. Effective C++ | 항목 16 new와 delete를 사용할 때는 형태를 반드시 맞추자 항목 16 new와 delete를 사용할 때는 형태를 반드시 맞추자 16.1 객체와 객체 배열의 메모리 구조 new 표현식을 사용해서 어떤 객체를 동적 할당하면 두 가지 내부 동작이 진행된다. 일단 operator new 함수가 사용되어 메모리가 할당된다. 그다음, 할당된 메모리에 대해 한 개 이상의 생성자가 호출된다. 반면, delete 표현식을 사용하면 또 다른 두 가지 내부 동작이 진행되는데, 우선 할당된 메모리에 대해 한 개 이상의 소멸자가 호출되고, 그 후에 operator delete 함수가 사용되어 메모리가 해제된다. new로 힙에 만들어진 객체의 메모리 배치 구조(layout)는 객체 배열의 메모리 배치 구조와 다르다. 특히, 배열을 위해 만들어지는 힙 메모리에는 대개 배열의 원소 개수, .. 2022. 1. 25. Effective C++ | 항목 15 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자 항목 15 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자15.1 RAII 클래스의 변환 자원을 가지고 무엇인가 해야 할 때 자원 관리 클래스만 사용하면 좋겠지만, 이미 현장에서 쓰고 있는 수많은 API는 자원을 직접 참조하도록 만들어져 있어 자원 관리 객체의 보호벽을 넘어가서 자원을 직접 다루어야 할 일이 종종 있다. 항목 13에서 createInvestment 팩토리 함수를 호출한 결과, 그 포인터를 담기 위해 shared_ptr와 같은 스마트 포인터를 사용했었다. 이때 Investment 객체를 사용하는 daysHeld 함수를 다음과 같이 호출하고 싶을 수 있다.int daysHeld(const Investment* pi); /* 주식을 매수한 후 경과한 날 수 */std::s.. 2022. 1. 25. Effective C++ | 항목 14 자원 관리 클래스의 복사 동작을 고찰하자 항목 14 자원 관리 클래스의 복사 동작을 고찰하자14.1 RAII 클래스의 복사 동작 자원 관리 클래스를 스스로 만들어야 하는 경우가 있다. 예를 들어, Mutex 타입의 뮤텍스 객체로 C API를 사용하고 있다고 가정해보자. RAII 법칙에 따라 이전에 걸어 놓은 뮤텍스 잠금을 풀어주는 Lock 클래스는 다음과 같이 정의할 수 있다.void lock(Mutex* pm); /* pm이 가리키는 뮤텍스의 잠금을 설정하는 C API 함수입니다. */void unlock(Mutex* pm); /* pm이 가리키는 뮤텍스의 잠금을 해제하는 C API 함수입니다. */class Lock {public: explicit Lock(Mutex* pm) : mutexPtr(pm) { lock(mutexPtr); /*.. 2022. 1. 24. Effective C++ | 항목 13 자원은 객체로 관리하자 항목 13 자원은 객체로 관리하자13.1 자원 관리 클래스 투자를 모델링해주는 클래스 라이브러리에 Investment라는 최상위 클래스가 있고 이것을 기본으로 다양한 투자 클래스가 파생되어 있다고 가정해보자. 이 라이브러리는 Investment에서 파생된 클래스의 객체를 사용자가 얻어내는 용도로 팩토리 함수(factory function)를 쓰도록 만들어져 있다.class Investment { ... }; /* 여러 형태의 투자를 모델링한 최상위 클래스 Investment */Investment* createInvestment(); /* Investment 클래스 계통의 객체를 동적 할당하고 그 포인터를 반환하는 팩토리 함수 */ createInvestment 함수를 통해 얻은 객체를 사용할 일이 없.. 2022. 1. 23. 전문가를 위한 C++ | Chapter 07 메모리 관리(상) 7.1 동적 메모리 다루기 메모리는 컴퓨터의 로우 레벨 구성 요소에 속하지만, 실력 있는 C++ 프로그래머가 되기 위해서는 동적 메모리를 처리하는 과정을 확실하게 이해하고 넘어가야 한다. 7.1.1 메모리 작동 과정 이 책에서는 메모리 한 칸을 레이블이 달린 상자로 표현한다. 여기서 레이블은 그 메모리를 사용하는 변수의 이름에 해당한다. 그리고 상자에 담긴 데이터는 그 변수에 현재 저장된 값이다. int i = 10; int* ptr = nullptr; ptr = new int; 예를 들어 그림 7-1 왼쪽은 다음 코드를 실행한 후의 메모리 상태를 표현한 것이다. 지역 변수 i를 자동 변수(automatic variable)라고 부르며 스택에 저장된다. 프로그램 실행 흐름이 이 변수가 선언된 유효 범위(.. 2022. 1. 20. 전문가를 위한 C++ | Chapter 09 클래스와 객체 마스터하기(하) 9.3 메서드의 종류 C++에서 제공하는 메서드의 종류는 다양하다. 이 절에서 하나씩 자세히 소개한다. 9.3.1 static 메서드 메서드도 데이터 멤버처럼 객체 단위가 아닌 클래스 단위로 적용되는 것이 있다. 이를 정적(static) 메서드라 부른다. 예를 들어 8장에서 정의한 SpreadsheetCell 클래스를 살펴보자. 여기서 stringToDouble와 doubleToString 헬퍼 메서드는 객체 정보에 접근하지 않기 때문에 다음과 같이 static으로 선언할 수 있다. /* static 메서드 */ class SpreadsheetCell { private: static std::string doubleToString(double inValue); static double stringToDo.. 2022. 1. 16. 전문가를 위한 C++ | Chapter 09 클래스와 객체 마스터하기(상) 9.1 friend C++는 클래스 안에서 다른 클래스나 다른 클래스의 멤버 함수, 그리고 멤버가 아닌 독립 함수를 friend로 선언하는 기능을 제공한다. friend로 지정된 대상은 이 클래스의 protected, private 데이터 멤버와 메서드에 접근할 수 있다. class Foo { friend class Bar; /* 클래스를 프렌드로 지정합니다. */ friend void Bar::processFroo(const Foo& foo); /* 특정한 메서드만 프렌드로 지정합니다. */ friend void dumpFoo(const Foo& foo); /* 독립 함수를 프렌드로 지정합니다. */ }; 프렌드로 지정할 클래스, 메서드, 그리고 함수는 반드시 접근하고자 하는 클래스 안에서 지정해야 한.. 2022. 1. 14. Effective C++ | 항목 12 객체의 모든 부분을 빠짐없이 복사하자 항목 12 객체의 모든 부분을 빠짐없이 복사하자 12.1 사용자가 선언한 복사 함수 객체의 안쪽 부분을 캡슐화한 객체 지향 시스템을 잘 보면 객체를 복사하는 함수가 딱 둘만 있을 것을 알 수 있다. 복사 생성자와 복사 대입 연산자라고 이 둘을 통틀어 복사 함수(copy function)라고 부른다. 객체 복사 함수를 여러분이 선언하면 이에 대해 컴파일러는 썩 반기는 분위기가 아니라는 듯, 여러분이 구현한 복사 함수가 잘못되었을 경우에도 입을 다물어 버린다. 고객을 나타내는 클래스가 하나 있다고 가정해보자. 이 클래스의 복사 함수는 호출될 때마다 로그를 남기도록 작성되었다. void logCall(const std::string& log); class Customer { /* 고객을 나타내는 클래스입니다... 2022. 1. 12. Effective C++ | 항목 11 operator=에서는 자기대입에 대한 처리가 빠지지 않도록 하자 항목 11 operator=에서는 자기 대입에 대한 처리가 빠지지 않도록 하자 자기 대입(self assignment)이란 어떤 객체가 자기 자신에 대해 대입 연산자를 적용하는 것을 말한다. class Widget { ... }; Widget w; w = w; /* 아주 적법한 코드입니다. */ a[i] = a[j]; /* i와 j가 같은 값이면 자기 대입됩니다. */ *px = *py; /* px와 py가 가리키는 대상이 같으면 자기 대입됩니다.*/ 이러한 자기 대입이 생기는 이유는 여러 곳에서 하나의 객체를 참조하는 상태, 다시 말해 중복 참조(ailasing) 때문이다. 같은 타입으로 만들어진 객체 여러 개를 참조자 혹은 포인터로 물어 놓고 동작하는 코드를 작성할 때는 같은 객체가 사용될 가능성을 .. 2022. 1. 12. 이전 1 2 3 4 5 다음