Object Oriented Programming(C++)60 Effective C++ | 항목 10 대입 연산자는 *this의 참조자를 반환하게 하자 항목 10 대입 연산자는 *this의 참조자를 반환하게 하자 10.1 대입 연산자와 반환 타입 관례 C++의 대입 연산은 여러 개가 사슬처럼 엮일 수 있는 성질과 우측 연관(right associative) 연산이라는 재미있는 특성을 갖고 있다. int, x, y, z; x = y = z = 10; x = (y = (z = 10)); 이렇게 대입 연산이 사슬처럼 엮이려면 대입 연산자가 좌변 인자에 대한 참조자를 반환하도록 구현되어 있을 것이다. 이런 구현은 일종의 관례(convention)인데, 여러분이 나름대로 만드는 클래스에 대입 연산자가 들어간다면 이 관례를 지키는 것이 좋다. 이 규칙은 단순 대입형 연산자 말고도 모든 형태의 대입 연산자에서 지켜져야 한다. class Widget { public:.. 2022. 1. 11. Effective C++ | 항목 09 객체 생성 및 소멸 과정 중에는 가상 함수를 절대로 호출하지 말자 항목 09 객체 생성 및 소멸 중에는 가상 함수를 절대로 호출하지 말자 9.1 객체 생성 및 소멸 중 가상 함수 잘못 호출하기 주식 거래를 본떠 만든 클래스가 있다고 가정하자. 매수 주문, 매도 주문 등의 거래를 모델링하는 데 중요한 포인트는 감사(audit) 기능이 있어야 한다는 점이다. 다음과 같이 주식 거래 객체가 생성될 때마다 감사 로그에 적절한 거래 내역이 만들어지도록 해보자. class Transaction { /* 주식 부모 클래스 */ public: Transaction(); virtual void logTransaction() const = 0; /* 거래 로그를 기록하는 순수 가상 메서드입니다. */ }; class BuyTransaction : public Transaction { /.. 2022. 1. 11. 전문가를 위한 C++ | Chapter 08 클래스와 객체 숙달하기 8.1 스프레드시트 예제 이 장과 다음 장에서는 실제로 실행할 수 있는 간단한 스프레드시트 예제를 이용하여 여러 가지 개념을 소개한다. 여기서 만들 스프레드시트는 셀(cell)이란 단위로 구성된 2차원 격자로서, 각 셀은 숫자나 스트링(string)을 담을 수 있다. 스프레드시트 예제 애플리케이션은 Spreadsheet와 SpreadsheetCell이란 기본 클래스를 사용한다. Spreadsheet 객체마다 SpreadsheetCell 객체를 가진다. 그리고 이러한 Spreadsheet를 관리하는 SpreadsheetApplication이란 클래스도 정의한다. 이 장에서는 SpreadsheetCell을 중심으로 소개한다. 8.2 클래스 작성 방법 클래스를 작성하려면 그 클래스의 모든 객체에 적용할 동작(.. 2021. 12. 30. Effective C++ | 항목 08 예외가 소멸자를 떠나지 못하도록 붙들어 놓자 항목 08 예외가 소멸자를 떠나지 못하도록 붙들어 놓자 8.1 예외를 내보내는 소멸자 소멸자에서는 예외가 발생한 조건이 어떤 조건인지에 따라 프로그램이 종료되던지 아니면 정의되지 않은 동작을 보인다. 이렇게 완전하지 못한 프로그램의 종료나 정의되지 않은 동작의 원인은 바로 예외가 터져 나오는 것을 내버려 두는 소멸자에게 있다. C++는 예외를 내보내는 소멸자를 싫어한다. ■ 8.1.1 소멸자의 예외 처리 여러분이 데이터베이스 연결을 나타내는 클래스를 쓰고 있다고 가정해보자. class DBConnection { public: ... static DBConnection create(); void close(); /* 연결을 닫습니다. 실패하면 예외를 던집니다. */ }; class DBConn { /* D.. 2021. 8. 29. Effective C++ | 항목 07 다형성을 가진 부모 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자 항목 07 다형적인 부모 클래스는 가상 소멸자를 선언하자 7.1 부모 클래스와 가상 소멸자 ■ 7.1.1 가상 소멸자의 선언 팩토리 함수(factory function) 새로 생성된 자식 클래스 객체에 대한 부모 클래스 포인터를 반환하는 함수를 말한다. 어떤 객체에 대한 포인터를 반환하는 용도로 사용한다. 팩토리 함수의 규칙 getTimeKeeper 함수에서 반환되는 객체는 힙에 있다. 객체를 사용하지 않으면 지원 누출을 막기 위해 객체를 적절히 삭제(delete)해야 한다. getTimeKeeper 함수가 반환하는 자식 클래스(AtomicClock) 객체를 부모 클래스의 포인터로 삭제한다. // 시간을 기록하는 TimeKeeper 클래스입니다. class TimeKeeper { public: TimeK.. 2021. 8. 29. Effective C++ | 항목 06 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해버리자 항목 06 컴파일러가 만든 함수가 필요 없으면 사용을 금하자 6.1 복사를 지원하지 않는 클래스 class HomeForSale { public: HomeForSale() { }; }; HomeForSale h1; HomeForSale h2; HomeForSale h3(h1);// h1을 자동으로 복사합니다. h1 = h2;// h2를 자동으로 복사합니다. 복사 생성자와 복사 대입 연산자가 저절로 만들어지는 것을 막기 위해 private 멤버로 선언한다. 컴파일러는 디폴트 버전을 생성하지 않고 비공개(private)의 접근성을 가지므로 외부 호출을 차단할 수 있다. private 멤버 함수는 그 클래스의 멤버 함수와 friend 함수가 호출할 수 있으므로 아예 정의(define)하지 않아 링크 시점에서 .. 2021. 8. 26. Effective C++ | 항목 05 C++가 은근슬쩍 만들어 호출해버리는 함수들에 촉각을 세우자 항목 05 C++가 은근슬쩍 만들어 호출해버리는 함수들 5.1 컴파일러가 선언하는 디폴트 멤버 함수 컴파일러가 기본으로 선언하는 멤버 함수는 다음과 같다. 생성자(constructor) 복사 생성자(copy constructor) 소멸자(destructor) 복사 대입 연산자(copy assignment operator) 컴파일러가 만드는 함수는 모두 기본형(default)이고 public 멤버이며 inline 함수다. class Empty { }; class Empty { public: Empty() { ... };// 디폴트 생성자 Empty(const Empty& rhs) { ... };// 디폴트 복사 생성자 ~Empty() { ... };// 디폴트 소멸자 Empty& operator=(cons.. 2021. 8. 26. Effective C++ | 항목 04 객체를 사용하기 전에 반드시 그 객체를 초기화하자 항목 04 객체를 사용하기 전에 반드시 그 객체를 초기화하자 4.1 비멤버 객체 초기화 C++는 객체(변수)를 초기화하는 데 있어 언제 초기화가 보장되며 언제 그렇지 않은지 규칙이 명확하게 준비되어 있다. 그러나 안타까운 점은 그 규칙 자체가 머리에 새겨두기엔 너무 복잡하다는 것이다. 따라서 가장 좋은 방법은 모든 객체를 사용하기 전에 항상 초기화하는 것이다. 기본제공 타입으로 만들어진 비멤버 객체에 대해서는 초기화를 손수해야 한다. /* int의 직접 초기화 */ int x = 0; /* 포인터의 직접 초기화 */ const char* const text = "A C-style string"; /* 입력 스트림에서 읽음으로써 초기화 */ double d; std::cin >> d; 4.2 멤버 객체 초.. 2021. 8. 26. Effective C++ | 항목 03 낌새만 보이면 const를 들이대보자 2021. 8. 26. Effective C++ | 항목 02 #define을 쓰려거든 const, enum, inline을 떠올리자 항목 02 #define을 쓰려거든 const, enum, inline을 떠올리자 2.1 매크로 상수 대신 const 상수 #define ASPECT_RATIO 1.653 우리에겐 이 ASPECT_RATIO가 기호식 이름(symbolic name)으로 보이지만, 선행 처리자는 소스 코드가 컴파일러에게 넘어가기 전에 ASPECT_RATIO를 밀어버리고 숫자 상수로 바꾸어 버린다. 그 결과, ASPECT_RATIO라는 이름은 컴파일러가 쓰는 기호 테이블에 들어가지 않는다. 그래서 숫자 상수로 대체된 코드에서 컴파일 에러가 발생하게 되면 대체 1.653이 어디서 왔는지 찾느라 시간을 허비하게 된다. 마찬가지로 기호 테이블에 이름이 들어가지 않기 때문에 기호식 디버거(symbolic debugger)에서도 문제.. 2021. 8. 21. Effective C++ | 항목 01 C++를 언어들의 연합체로 바라보는 안목은 필수 항목 01 C++를 언어들의 연합체로 바라보는 안목은 필수 1.1 C++는 다중 패러다임 프로그래밍 언어 오늘날의 C++는 다중 패러다임 프로그래밍 언어(multiparadigm programming language)라고 불린다. 절차적 프로그래밍을 기본으로 하여 객체 지향, 함수식, 일반화 프로그래밍을 포함하며 메타 프로그래밍 개념까지 지원하고 있다. 이런 엄청난 표현력과 유연석 덕분에 C++는 소프트웨어 개발에 있어 대체할 만한 것이 없는 도구가 되었지만, 혹자에게 어느 정도 혼동을 줄 여지가 있는 것도 사실이다. 가장 쉬우면서 정확한 방법은 C++를 상관 관계가 있는 여러 언어들의 연합체(federation)로 보는 것이다. C++를 제대로 따라잡으려면 이 언어가 여러 개의 하위 언어(sublang.. 2021. 8. 20. C++ | 04-3 생성자와 소멸자(Constructor and Destructor) 1. 생성자 1.1 생성자의 선언과 정의 새로운 객체를 생성하고 멤버 변수를 private으로 선언하면 이 멤버 변수를 초기하는 멤버 함수를 부득이하게 정의해야 했다. 그러나 멤버 변수를 초기화하기 위해 매번 멤버 함수를 정의하는 것은 여간 번거로운 일이 아니다. 다행히 C++는 특별한 멤버 함수, 생성자(Constructor)를 제공한다. 생성자는 객체의 생성과 동시에 멤버 변수를 초기화해주는 멤버 함수로 객체를 생성할 때 딱 한 번만 호출된다. 생성자를 정의하려면 다음과 같은 형식을 따르면 된다. ① 클래스의 이름과 같다. 생성자는 클래스의 이름과 완전히 같고, 보통 public으로 선언한다. class Overwatch { private: string name; int age; public: /* .. 2021. 8. 10. 이전 1 2 3 4 5 다음