인기 글
-
5. 구현
항목 30: 인라인 함수는 미주알고주알 따져서 이해해 두자.
인라인함수 = 함수 호출문 -> 함수 본문으로 바꿔치기 인라인 함수의 장점 인라인 함수 => 함수처럼 보이고, 함수처럼 동작하고, 매크로보다 훨씬 안전하고(항목 2 참조), 함수 호출 시 오버헤드도 걱정할 필요 없고 + 컴파일러 최적화는 함수 호출이 없 코드가 연속적으로 이어지는 구간에 보통 적용되도록 설계되었기 때문에, 인라인 함수를 사용하면 컴파일러가 함수 본문에 대해 문맥별(context-specific) 최적화를 걸기가 쉽다. 아웃라인 함수엔 적용X 인라인 함수의 단점 목적 코드의 크기가 커진다!!! => 제한된 메모리 환경에서는 코드가 메모리에 다 올라가지 못할 수도 있고, 가상 메모리 환경이더라도 페이징 횟수가 늘어나고, 명령어 캐시 적중률이 떨어질 가능성이 높다. [운영체제 OS] 메모리 관..
-
2. 생성자, 소멸자 및 대입 연산자
항목 11: operator=에서는 자기대입에 대한 처리가 빠지지 않도록 하자
자기대입 = self assignment a=a; a[i] = a[j]; // i==j일시 자기대입 *pa = *pb; // pa와 pb가 같은 객체를 가르킬 시 자기대입 void doSomething(const Base& pb, Derived* pd) // pb와 pd가 같은 객체를 가르킬 가능성이 있음 모두 다 자기 대입의 가능성이 있거나, 자기 대입임 중복참조(aliasing) == 여러곳에서 하나의 객체를 가르킴 => 자기대입 가능성 참고) 왜 this == &t 를 비교하냐? 만약 t = t; 이렇게 되있으면(Self Copy) 저게 없으면 t를 지워버리고 다시 할당받을것을 가르키는데 문제는 복사할 구조체도 같이 없어지기 때문에 복사가 안됨 >> Self Copy이면 바로 Return 해버림 A..
-
6. 상속, 그리고 객체 지향 설계
항목 39: private 상속은 심사숙고해서 구사하자
C++은 public 상속을 is-a 관계로 나타낸다.(항목 32 참고) Student가 Person으로부터 public 상속으로 파생된 형태의 클래스 계통이 주어졌다고 가정하면, 함수 호출을 성공시키기 위해 컴파일러가 Student를 Person으로 암시적 변환을 수행하는 예제를 통해 is-a 관계를 설명했었다. 이 예제를 private 상속으로 살짝 바꿔보자. private 상속은 분명 is-a 관계를 뜻하지 않는다. 그럼 뭘까? 일단 private 상속의 동작 규칙부터 알아보자. private 상속의 동작 규칙 파생 클래스 객체(Student)를 기본 클래스(Person)으로 변환하지 않는다. 기본 클래스로부터 물려받은 맴버는 파생 클래스에서 모조리 private 맴버가 된다. 즉 기본 클래스에서 ..
-
6. 상속, 그리고 객체 지향 설계
항목 36: 상속받은 비가상 함수를 파생 클래스에 재정의하는 것은 절대 금물!
D라는 이름의 클래스가 B라는 이름의 클래스로부터 public 상속에 의해 파생되었고, B 클래스에는 mf()라는 public 맴버 함수가 정의되어 있다고 가정해보자. 여기서의 pB->mf() 이 당연히 이런식으로 동작할 것이라고 예상할 수 있다. 왜? 둘 다 같은 객체인 x에 대해 mf()를 호출하고 있기 때문이다. 하지만 당연하지 않을 수도 있다는 것이 문제이다. 특히 mf()가 비가상 함수이고 D 클래스가 자체적으로 mf() 함수를 또 정의하고 있는 경우 아래 코드와 같은 황당한 일이 벌어진다. 이렇게 같은 객체에서 같은 함수를 호출하는데, 실제로는 다른 함수를 호출하는 이유는, 비가상 함수는 정적 바인딩(static binding)으로 묶이기 때문이다.(항목 37 참고) => 즉 pB가 가르키는 ..
-
6. 상속, 그리고 객체 지향 설계
항목 34: 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자
(public)상속 이라는 개념은 사실 2가지로 나뉜다. 인터페이스 상속 vs (함수)구현 상속 이 둘의 차이는 함수 선언과 함수 정의의 차이와 맥을 같이한다고 보면 된다. 클래스 설계자의 입장에서 맴버 함수의 인터페이스(선언)만을 파생클래스에 상속받고 싶은 경우 함수의 인터페이스 구현을 모두 상속받고 싶은 경우 상속받은 구현이 오버라이드가 가능하게 만들고 싶은 경우 어떤 것도 오버라이드할 수 없도록 막고 싶은 경우 이러저러한 선택사항이 나올 수 있는데, 이러한 선택사항들 사이의 차이점을 명확하게 몸으로 느끼는 것이 중요하다. 그래서 예를 들어보면, 그래픽 응용프로그램에 쓰이는 기하학적 도형을 나타내는 클래스 계통구조를 놓고 한번 생각해보자. Shape는 추상 클래스이다. 왜냐하면 맴버 함수인 draw(..