씨쁠쁠03

오젼·2022년 6월 4일
0

[cpp]

목록 보기
4/9
post-thumbnail

Borderlands

ex00

  • 상속 연습을 위한 첫 단계.

private 생성자

ex01

상속

  • C++에서 클래스 상속이란 기존에 정의되어 있는 클래스의 모든 멤버 변수와 멤버 함수를 물려받아, 새로운 클래스를 작성하는 것을 의미합니다.
  • https://modoocode.com/209

protected 접근제한자

  • private의 경우 어떠한 경우라도 같은 클래스 안에서만 접근 가능
  • protected는 private과 public의 중간. 상속받은 클래스 내에서는 접근 가능하지만 그 외의 경우는 접근 불가능.
  • https://thrillfighter.tistory.com/531 접근제한자 종류
class Derived : public Base
  • 상속 할 때 앞에 붙는 public, private protected 차이점
  • public: 기반 클래스에서 정해진 범위 그대로 가져옴
  • protected: 기반 클래스에서 public으로 설정된 것을 protected로 받아옴
  • private: 기반 클래스에 있던 모든 범위를 private으로 바꿈

오버라이딩

  • 상속시 기반 클래스의 함수와 동일한 함수를 파생 클래스에서도 정의해 주는 것을 오버라이딩이라 한다.

상속에서 생성자와 소멸자 순서

  • 클래스를 상속했을 때 생성자는 기반클래스 -> 파생클래스 순으로 호출
  • 소멸자는 파생클래스 -> 기반클래스 순으로 호출된다.

{} 중괄호

ex02

  • 상속 연습 + 다중 상속 연습을 위한 중간 단계

ex03

일반화 vs 구체화

업캐스팅

  • 파생클래스에서 기반클래스로 캐스팅 하는 것을 업캐스팅이라고 한다.
  • but, 다운캐스팅은 오류 생김. 기반클래스에서 없는 내용이 파생클래스에서 추가되기 때문
  • 강제적 다운캐스팅이 가능할 순 있지만 절대비추. 런타임 에러 발생 가능.

동적 바인딩

  • 컴파일 시에 어떤 함수가 실행될 지 정해지지 않고 런타임 시에 정해지는 일을 가리켜 동적 바인딩(dynamic binding)이라고 부른다.
  • virtual 키워드로 기반클래스 포인터를 사용하여도 파생클래스의 함수를 사용하도록 할 수 있음.

virtual, override 키워드

  • virtual은 가상 함수를 나타낼 때
  • override 키워드는 c++11부터 나온 키워드. 파생클래스에서 기반클래스의 가상함수를 오버라이드 하는 경우 override 키워드를 통해 명시적으로 나타낼 수 있게 됨.
  • 오버라이드를 하려면 함수형이 완전히 같아야 함. override 키워드를 쓰면 오버라이드가 이뤄진 게 맞는지 더 정확하게 판단할 수 있음.(함수꼴이 달라 오버라이드가 이뤄지지 않는 경우 오류 발생함)

virtual 함수 동작 원리

  • 컴파일러는 가상함수가 1개라도 존재하는 클래스에 대해 가상함수 테이블(virtual function table - aka vtable)을 만들고 테이블에 접근할 수 있는 멤버변수 포인터를 만든다. 대신 이 포인터는 은닉되어 있다.
  • vtable 안엔 클래스의 멤버함수와 가상함수가 key와 value를 갖고 테이블의 형태로 존재한다. (key: 함수명 value: 함수포인터 주소)
  • 이 때 기반클래스의 가상함수를 오버라이딩한 파생클래스의 함수는 vtable에 기록되지 않는다. 대문에 오버라이딩 된 가상함수를 호출하면, 무조건 가장 마지막에 오버라이딩을 한 파생 클래스의 멤버함수가 호출된다.
  • 가상함수가 포함되면 가상함수 테이블이 생성되고 테이블을 참조하여 호출할 함수를 결정하는 과정에서 실행속도가 저하된다.
  • 때문에 c보다 c++이 실행속도가 구림
  • 하지만 장점이 더 많기 때문에 사용됨
  • https://nomad-programmer.tistory.com/359

기반클래스에서 virtual 키워드

  • https://luv-n-interest.tistory.com/1174
  • 기반클래스에서 virtual로 선언한 함수는 파생클래스에 있는 같은 시그니처의 함수들에게 자동으로 virtual로 선언됨!
  • 자식 클래스에서 명시적으로 override를 하는 경우 암묵적으로 virtual이라는 가정 하에 작성하기 때문에 virtual 키워드를 사용하지 않음.

그럼 모든 함수를 가상함수로 만들면 안 되나?

  • https://modoocode.com/211
  • 실제로 자바에선 모든 함수들이 디폴트로 virtual로 선언됨.
  • 오버헤드 문제가 있음. 최적화와 관련한 문제라고 생각하면 됨. 위에서 vtable사용 방법에서 봤듯이 가상함수를 이용하게 되면 함수를 사용할 때 약간 더 느릴 수밖에 없음.

다중상속

  • c++은 다중상속을 허용한다.
  • 다중상속시 생성자 호출 순서는 상속 순서에 따른다.

가상상속

  • 다이아몬드 상속을 하려다 보면 변수 접근에도 문제가 생기고 생성자, 소멸자가 두 번씩 호출되게 된다.
  • 이를 해결하기 위해 사용할 수 있는 것이 가상상속
  • https://hwan-shell.tistory.com/224
  • 가상상속을 사용하게 되면 생성자, 소멸자를 중복으로 호출하는 문제와 변수 접근 문제를 해결할 수 있지만 대신 데이터 크기는 더 커지게 된다.
  • 그 이유는 virtual base table을 생성하고 그 테이블을 이용하여 클래스에 접근하게 되기 때문.
  • 이는 성능저하를 야기할 수 있음

-Wshadow, -Wno-shadow option

  • Wshadow option: 지역변수가 다른 지역변수, 매개변수 등(shadow) 덮는 경우 Warning이 발생
  • 이것은 선언된 변수명을 다른 scope에서 다시 선언한 경우 경고를 발생시킨다. 이렇게 변수가 선언될 경우 이것을 shadowing변수라고 한다. 다음의 코드를 확인해 보도록 하자. https://www.joinc.co.kr/w/Site/SoftWare_engineering/Refactoring/Refactoring03

0개의 댓글