Ex00
문제 이해
- energy point
- attack, repair을 하기 위해 필요하다.
- 스타크래프트의 미네랄과 유사한 개념
- hit point : 체력 (hp)
Q&A
- this 키워드를 쓰는 이유?
- 현재 객체의 멤버 변수와 매개변수로 받은 인자의 이름을 구별하기 위해
- 소멸자 개념
1 2 3 4 5
int main() { ClapTrap b("kim"); b.~ClapTrap(); std::cout << b.getName() << std::endl; }
- 명시적으로 소멸자를 호출할 수 있을까? 스코프를 빠져나갈 때 소멸자가 다시 호출되는 이유?
- 명시적으로 호출했기 때문에 소멸자가 실행된 것이고, 이후에 main 스코프를 빠져나갔기 때문에 소멸자가 다시 호출된 것이다.
- 소멸자는 호출되는 대로 실행된다. 이전에 한번 실행했다고 이후에 실행되지 않는 것이 아니다.
- 멤버 변수에 접근 가능한 이유?
- 디폴트 소멸자는 객체의 메모리를 해제하는 것이 아니기 때문에 접근이 가능하다.
- 명시적으로 소멸자를 호출할 수 있을까? 스코프를 빠져나갈 때 소멸자가 다시 호출되는 이유?
Ex01
주요 개념
- virtual 키워드
- 함수에 붙여주어 파생 클래스에서 재정의 된다는 것을 명시
Q&A
- 상속받을 때의 접근제어자의 의미? (예.
class Derived : public Base
)- 파생 클래스에서 상속받은 기반 클래스 멤버들의 접근 제어자를 설정한다.
- public : 기반 클래스와 접근 제어자를 동일하게 상속받음.
- protected : public 멤버만 protected로 변경한 채로 상속받음.
- private : 모든 멤버들을 private으로 변경한 채로 상속받음.
- ClapTrap의 private 멤버를 protected로 변경하는 이유?
- 파생 클래스에서 초기화 리스트로 초기화할 수 없는 이유?
- 부모의 생성자가 먼저 호출되어 초기화를 진행하기 때문.
인자를 넘겨줘도 디폴트 생성자로 객체 생성하는 문제
- 기반 클래스의 디폴트 생성자가 아닌 다른 생성자를 호출하려면 명시적으로 호출해야한다.
- ClapTrap 소멸자에만 virtual 키워드를 붙이고, 생성자에는 안붙이는 이유?
- 생성자와 달리 소멸자는 항상 파생클래스가 먼저 호출되어야 하기 때문.
- ScavTrap 생성자에서의
:ClapTrap(name)
의 의미?- 기반 클래스의 특정 생성자를 호출하는 것.
- 디폴트 생성자를 호출하려는 경우에는 필요 없다.
Ex03
주요 개념
다중 상속
- 두 개 이상의 클래스로부터 멤버를 상속받아 파생 클래스를 생성하는 것.
- 문제점
- 상속받은 클래스가 동일한 멤버명을 가질 수 있다.
- 해결책 :
Derived::BaseB()
와 같이 어떤 클래스의 멤버를 사용할지 명시해준다.
- 해결책 :
- 다이아몬드 상속
- 상속받은 클래스가 동일한 멤버명을 가질 수 있다.
다이아몬드 상속
- 다중 상속을 받을 때 이들의 기반 클래스가 동일한 경우
- 문제점
- B, C가 겹치지 않더라도 A의 모든 내용이 겹친다.
- 해결방법
- B, C가 A를 상속받을 때
public virtual
로 상속받는다.(가상 상속)- 이를 통해 기반 클래스 A를 한 번만 상속받을 수 있다.
- B, C가 A를 상속받을 때
-Wshadow, -Wno-shadow
-Wshadow
- 한 scope에서 선언된 변수가 다른 scope에서도 선언된 경우 경고 발생
Q&A
- 다중 상속에서 생성자를 정의할 때
:DerivedA(a), DerivedB(b), DerivedC(c)
와 같이 기반 클래스의 생성자를 모두 명시적으로 호출해야할까?- 디폴트 생성자를 호출하려고 한다면 생략해도 된다.
- 객체 생성시에 인자를 넣어야 하는 경우는 초기화리스트를 사용해서 호출해야한다.
- 복사 생성할 때, 변수 접근 방법
- 직접 접근 vs getter를 통한 접근
- 변수에 직접 접근하는 것이 더 효율적이다.
전체
Q&A
- 복사 생성자 내부에서 할당 대입 연산자를 활용하는 방식의 문제점
- 다음과 같이 기반 클래스의 변수만 복사가 되는 경우를 slicing이라고 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
class Base { public: int x; Base& operator=(const Base& other) { x = other.x; return *this; } }; class Derived : public Base { public: int y; Derived& operator=(const Derived& other) { Base::operator=(other); y = other.y; return *this; } Derived(const Derived& other) { *this = other; } }; int main() { Derived d1; d1.x = 1; d1.y = 2; Derived d2 = d1; // 여기서 slicing이 발생 std::cout << d2.x << " " << d2.y << std::endl; // 출력: 1 0 }
Ref.
- [C++] 상속과 생성자 (파생 클래스 구현 방법 및 호출 순서)
- Multiple inheritance - Wikipedia
- c++ - member initializer does not name a non-static data member or base class - Stack Overflow
- c++ - Destructor being called twice when being explicitly invoked - Stack Overflow
- c++ - explicit call to destructor is not destroying my object why? - Stack Overflow