전체 글 348

[C++] 정사각형-직사각형 문제

정사각형-직사각형 문제앞에서 다이아몬드 문제에 의한 객체지향의 한계점을 살펴봤다면, 이번에는 정사각형-직사각형 문제로부터 객체지향의 한계점을 살펴보자#include using namespace std;class Rectangle { // 직사각형 public: Rectangle(double a, double b) : a(a), b(b) {} private: double a, b;};class Square { // 정사각형 public: Square(double a) : a(a) {} private: double a;};정사각형 is a 직사각형네 변의 길이 모두따라서 정사각형과 직사각형을 상속관계로 구현해보자정사각형 is a 직사각형 이므로, 정사각형은 직사각형으로..

[C++] 다중 상속과 다이아몬드 문제

다중 상속과 다이아몬드 문제한 클래스가 여러 부모를 가지고 있는 경우를 다중 상속이라고 한다cf) 자바와 C#은 다중 상속을 허용하지 않음#include using namespace std;struct Mom { int a = 1;};struct Dad { int b = 2;};struct Child : Mom, Dad { int c = 3;};int main() { Child ch; cout 여기까지는 문제가 없다.만약 Dad의 멤버 변수가 b가 아니라 a라면?#include using namespace std;struct Mom { int a = 1;};struct Dad { int a = 2;};struct Child : Mom, Dad { int c = ..

[C++] 객체 지향 프로그래밍의 4대 원칙(원리)

객체 지향 프로그래밍(OOP)의 4대 원리캡슐화(Encapsulation)상속성(Inheritance)다형성(Polymorphism)추상화(Abstraction)캡슐화(Encapsulation)What?데이터(멤버 변수)와 기능(멤버 메서드)을 하나의 단위로 묶어 놓음데이터 은닉접근 제어를 통해 멤버 변수는 숨기고, Getter와 Setter와 같은 데이터 접근을 위한 메서드를 노출When?언제든!Why?클래스를 사용하는 사람은 멤버 메서드 사용법만 알면 되고, 클래스 내부 구조에 대한 이해가 필요하지 않음사용자가 데이터를 실수로 잘못 바꾸는 것을 방지How?클래스 안에 멤버 변수, 멤버 메서드 선언 / 접근 제어상속성(Inheritance)What?부모 클래스의 멤버를 재사용해서 자식 클래스에서도 사용..

[C++] 상속에서의 형변환 - RTTI와 dynamic_cast

상속에서의 형변환 - RTTI와 dynamic_caststatic_cast: 정적인 시간(컴파일 타임)에 캐스팅이 일어남dynamic_cast : 동적인 시간(런타임)에 캐스팅이 일어남복습! static castclass Base { public: int x;};class Derived : public Base { public: int y;};int main() { Base *b = new Derived; Derived *d = static_cast(b);}b가 가리키는 인스턴스의 타입을 알고 있다면, static_cast를 이용하여 형변환을 해줄 수 있었다RTTI(Run Time Type Information/Identification)b가 실제로 어떤 타입을 가리키는지 컴..

[C++] 상속에서의 형변환 - 다운캐스팅

상속에서의 형변환 - 다운캐스팅(Downcasting)다운 캐스팅 : 부모 클래스에서 자식 클래스로 내려 보내는 형태의 캐스팅static_cast와 dynamic_cast가 있다.static : 정적인 시간(컴파일 타임)에 발생하는 캐스팅ex) double->int, int->double다음과 같은 클래스가 있다고 해보자#include using namespace std;class Base { public: int a = 1;};class Drv1 : public Base { public: void f() { cout b에서는 멤버 변수 a만 접근이 가능하다b에서도 자식 클래스의 고유 멤버에 접근을 해보고 싶다그러면 b가 가리키는 객체를 Drv *d1 = b로 넣을 수 있지..

[C++] 상속에서의 형변환 - 업캐스팅(Upcasting)

상속에서의 형변환 - 업캐스팅(Upcasting)Based *b = new Derived;우리는 위와 같이 자식 클래스의 객체를 가리켜왔다. 이게 가능한 이유가 업 캐스팅(Upcasting) 때문이다.double a = 1이 가능한 이유는 double a = (double)1; 이라는 묵시적 변환이 이루어졌기 때문이다.int main() { Derived *d = new Derived; Base *b = d;}위와 같이 자식 클래스에서 부모 클래스로 올라가는 형태의 캐스팅을 업 캐스팅(Upcasting)이라고 한다Upcasting: 자식 클래스 포인터 -> 부모 클래스 포인터(묵시적)총각은 남자가 되도 문제가 없지만, 남자가 총각인 것은 아니다.그래서 자식 클래스 포인터(총각)를 부모 ..

[C++] 생성/소멸자 실행 순서와 가상 소멸자

생성/소멸자 실행 순서와 가상 소멸자상속 관계에서 생성자와 소멸자의 작동 과정에 대해 알아보자생성/소멸자 실행 순서#include using namespace std;class Ice { public: Ice() { cout 전에 말했던 것처럼 자식 클래스의 생성자가 호출 될 때 먼저 부모 클래스의 생성자가 호출된다PatBingsoo를 생성하면Pat, Bingsoo, Ice의 생성자가 모두 호출될 것이다소멸자도 마찬가지다.생성자와 소멸자의 순서를 예측해보자Ice() // PatBingsoo의 부모 클래스인 Bingsoo의 멤버인 ice가 제일 먼저 생성되었다.Bingsoo() // Bingsoo의 멤버 ice가 생성되고 Bingsoo가 생성되었다.Pat() // PatBingsoo의 멤버 pat..

[C++] 순수 가상 함수와 추상 클래스

순수 가상 함수(pure virtual function)와 추상 클래스(abstract class)이전 시간까지 가상 함수에 대해서 배웠다.아래 예시와 같이 가상 함수를 통해 오버라이딩을 할 수 있었다. #include using namespace std;class A { public: virtual void f() {}};class B : public A { public: void f() {}};int main() { A *a = new B; a->f(); delete a;}순수 가상 함수란 무엇인가요?가상이라는 것은 실제로는 존재하지 않는다는 의미인데, 이전 시간에서 다뤘듯 부모타입 포인터 변수가 부모타입 객체를 가리키면, 가상 함수 호출이 가능했다그래서 완..

[C++] 상속이 필요한 이유(2)

상속이 필요한 이유(2)상속이 필요한 이유(1) 코드#include #include using namespace std;class Message { public: Message(int sendTime, string sendName) { this->sendTime = sendTime; // this->sendTime을 안쓰고 sendTime을 쓰면 매개변수 값을 매개변수에 넣는 꼴. this->sendName = sendName; } int GetSendTime() const { return sendTime; } string GetSendName() const { return sendName; } private: int sendTime; s..

[C++] 가상 함수(Virtual Function)와 동적 바인딩(Dynamic Binding)

가상 함수(Virtual Function)와 동적 바인딩(Dynamic Binding)동적 바인딩 : 부모 클래스가 자식 클래스를 가리키고 있으면, 자식 클래스에 오버라이딩된 메서드를 실행할 수 있도록 동적으로 바인딩을 해준다.참고)동적 --> 런타임에 결정정적 --> 컴파일 타임에 결정Example) RPG 게임에서 무기 구현#include using namespace std;class Weapon { public: Weapon(int power) : power(power) { cout 자식 생성자가 호출되기 전에 반드시 부모 생성자가 호출된다mySword.Use()의 경우 Sword::Use()가 호출된다myMagic.Use()의 경우 Magic::Use()가 호출된다우리가 게임..