7월 18, 2016

[EC++ 07] Declare destructors virtual in polymorphic base classes.

  • Partial destruction problem
  • Base class pointer로 derived 객체를 가르키고 있을 때, 객체가 해제되면 base class의 dtor가 call됨. 이 경우 derived 객체에서 base class 부분의 resource는 해제되지만 derived class의 resource가 해제되지 않아 resource leak 발생하는데, 이를 partial destruction이라고 함.

  • Partial destruction을 막는 방법
  • Base class 의 dtor를 virtual로 선언. 단, 어떤 클래스가 base class 로 쓰이지 않는데도 virtual detruction을 implementation하는 것은 좋지 않음. 클래스에 virtual function이 있는 경우 virtual function을 관리하는 vtbl("virtual table")을 가르키는 vptr("virtual pointer")를 객체가 가지게 되는데, 이 때문에 객체의 크기가 커지게 됨.

  • Destructor call order
  • Derived class의 destructor부터 call되고 base class의 dtor가 마지막에 call됨.


Summary

  • Polymorphic base classes should declare virtual desturctors. If a class has any virtual functions, it should have a virtual destructor.
  • Classes not designed to be base classes or not designed to be used polymorphically should not declare virtual destructors.

Reference

  • Effective C++ by Scott Meyers

7월 14, 2016

[EC++ 06] Explicityly disallow the use of compiler-generated functions you do not want.

  • 방법1. member function을 private으로 선언하고 implementing을 하지 않음.
  • 방법2. member function call을 막는 base class를 생성하고 이를 상속함.
  • 단, 이 경우 multiple inheritance 가 되어 empty base class optimization (Item 40) 같은 몇가지 사소한 문제를 일으킬 수 있음.


Summary

  • To disallow functionality automatically provided by compilers, declare the corresponding member functions private and give no implementations. Using a base class like Uncopyable is one way to do this.

Reference

  • Effective C++ by Scott Meyers

7월 12, 2016

[EC++ 05] Know what functions C++ silently writes and calls.

  1. 사용자가 직접 선언하지 않아도 컴파일러가 자동적으로 정의하는 function이 존재.
  2. copy constructor, copy assignment operator, and destructor 등. 만약 사용자가 constructor를 하나도 직접 선언하지 않았다면 컴파일러가 default constructor 도 자동으로 선언. 이러한 function들은 모두 public, inline 함수로 선언됨.

  3. 상속 관계가 있는 클래스의 destructor 선언 시 주의
  4. Base class의 destructor가 virtual로 선언되지 않은 경우, derived class의 compiler-generated destructor는 non-virtual로 선언됨.

  5. Default construtor가 자동으로 생성되지 않는 경우
  6. 사용자가 단 하나의 constructor라도 직접 선언한다면 default constructor는 자동으로 생성되지 않음.

  7. 그 외 함수가 자동으로 생성되는 경우
  8. Copy constructor나 copy assignment operator의 사용자 선언이 없으면, 이러한 함수가 실제로 call 되며, legal하게 작동되는 경우에 한해 컴파일러가 함수를 생성할 수 있음.

  9. 컴파일러는 derived class가 base class에서 private으로 선언된 copy assignment operator를 implicitly call하는 것을 허용하지 않음.

Summary

  • Compilers may implicitly generate a class's default constructor, copy constructor, copy assignment operator, and destructor.

Reference

  • Effective C++ by Scott Meyers

7월 11, 2016

[EC++ 04] Make sure that objects are initialized before they're used.


  1. Initialization 규칙
  2. 일반적으로 C++의 C 부분에 해당하는 경우 자동 initializing을 보장하지 않는데, C++의 non-C 부분에 해당하는 경우엔 해주는 경우도 있음. ex)array는 초기화 X, vector는 초기화 O.
    따라서 object를 사용하기 전에는 초기화를 직접 해주고 사용해야 함.

  3. Initialization과 assignment를 헷갈리지 말 것.
  4. C++은 ctor의 body에 들어가기 전에 object를 초기화함. 가급적이면 ctor의 밖에서 true initialization (member initialization list를 사용)할 것. ctor의 body 안에서 멤버에 =operator를 사용하는 경우 initialization이 아니라 assignment가 일어나 효율이 떨어짐. built-in type의 경우 initialization과 assignment 사이에 차이가 없지만 일관성 위해 initialization 사용하는게 좋음.
    const 나 reference 같은 경우는 member initialization list를 통해서만 초기화할 수 있음.

  5. Initialization order
  6. 상속 관계 안에서는 항상 base class가 먼저, derived class가 나중에 초기화됨(ECpp 12 참조). 한 class 안에서는 member를 선언한 순서대로 초기화됨.

  7. Order of initialization of non-local static objects
    • A static object
    • 생성된 때부터 프로그램이 종료되는 순간까지 존재하는 object.

    • Translation unit
    • 하나의 object file을 만드는 source code 단위. 대게 하나의 source file과 거기에 include 된 모든 파일.

    서로 다른 translation unit 에 속해있는 non-local static object의 initialization의 상대적인 순서는 undefined. 이런 non-local static object를 상대적인 순서를 맞춰가며 초기화하는 것은 매우 어렵기 때문에, 각 non-local statice var.을 static으로 선언한 function에 넣고, function 내에서 초기화하고 var.을 refence로 반환하도록 하는 것이 좋음. (단, 멀티스레드 환경에서 이런 static object를 포함하는 function 사용 시 주의해야 함.)


Summary

  • Manually initialize objects of built-in type, because C++ only sometimes initializes them itself.
  • In a constructor, prefer use of the member initialization list to assignment inside the body of the constructor. List data members in the initialization list in the same order they're declared in the class.
  • Avoid initialization order problems across translation units by replacing non-local static objects with local static objects.

Reference

  • Effective C++ by Scott Meyers

7월 10, 2016

enum, enum VS enum class(struct)


enum

  • enum(enumeration)
  • enumerator: namespace 안에 const 선언된 값
  • enum은 하나의 자료형으로 취급돼, 이를 param.로 받는 함수의 overloading 가능

enum VS enum class(struct)

  • enum (= unmanaged enum = standard enum)
  • namespace가 구분되지 않기 때문에 같은 이름의 enumerator가 존재할 수 없음.

  • enum class (= unmanaged enum = C++/CX enum)
  • 각각 자신의 namespace가 있어 같은 이름의 enumberator를 가질 수 있음.



Reference


7월 07, 2016

[EC++ 03] Use const whenever possible.

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


operator overloading 의 반환구에 const 를 붙여줌.

const Test


const Member Functions

  1. member function에 쓰이는 const 의 목적은 const object로 member function을 불렀을 때 어느 member function이 불릴지 판별하는 것. member function에 const 를 붙이는 이유는 크게 두가지.
    1. object 내용을 수정하는 함수와 그렇지 않은 함수를 구분할 수 있게 함.

    2. const object를 이용한 작업을 가능하게 하는데, 이는 C++의 성능 향상을 이루는 매우 중요한 방법 중 하나임(EC++ 20 참조).
  2. const에는 physical constantness와 logical constantness의 두가지 개념이 존재.
  3. const member function 안에서도 특정 member field를 수정해야하는 경우가 있는데, 이러한 member field에 키워드 mutable을 붙이면 수정이 가능.

Avoiding Duplication in const and Non-const Member Functions

같은 함수를 const 버전과 non-const 버전으로 구현하는 과정에서의 코드 중복을 막을 수 있는 방법.

Summary

  • Declatring something const helps compilers detect usage errors. const can be applied to objects at any scope, to function parameters and return types, and to member functions as a whole.
  • Compilers enforce bitwise constness, but you should program using logical constness.
  • When const and non-const member functions have essentially identical implementations, code duplication can be avoided by having the non-const version call the const version.

Reference

  • Effective C++ by Scott Meyers