구체 클래스 함수의 구현체가 있는 클래스 추상 클래스 구현이 되어있지 않은 함수(순수 가상 함수)를 가진 클래스 // Animal.h class Animal { public: virtual ~Animal(); virtual void Speak() = 0; // 구현하지 않겠다는 의미. 순수 가상 함수라고 불린다. private: int mAge }; //Cat.h class Cat : public Animal { public: ~Cat(); void Speak(); private: char *mName; }; → Animal은 추상 클래스이고 Cat은 구체 클래스이다. 순수 가상 함수 구현체가 없는 멤버 함수 파생 클래스가 구현해야 한다. virtual void Speak() = 0; 이 함수를 구현하지..
전체 글
미지의 코딩세계로다중 상속 다중 상속은 사용하지 않는 것이 일반적이다. 생성자 호출 순서 파생 클래스에서 등장한 부모 클래스 순서대로 호출된다. 초기화 리스트의 순서는 상관 없다. → super()를 사용할 수 없는 이유는 다중 상속이 가능하기 때문입니다. 문제점1: 같은 이름의 함수 같은 이름의 함수가 있다면 호출될 함수를 명시적으로 지정해야 한다. > 어떤 함수를 호출해야하는지 모호하다면 컴파일이 안 되기 때문에 부모클래스를 특정해주어야 한다. 문제점2: 다이아몬드 문제 Liger는 몇 개의 2개의 Animal 클래스를 동시에 가지게 되는 문제가 발생. 다이아몬드 문제(Diamond Problem): 다중 상속을 사용할 때, 한 클래스가 두 개 이상의 클래스를 상속하고 그 두 클래스가 다시 같은 클래스를 상속하는 ..
비 가상 소멸자 // Animal.hpp class Animal { public: ~Animal(); private: int mAge; }; // Cat.hpp class Cat : public Animal { public: ~Cat(); private: char *mName; }; Cat myCat = new Cat(2, "Coco"); delete myCat; Animal yourCat = new Cat(4, "Mocha"); delete yourCat; 정적 바인딩의 경우 메모리 누수의 문제가 생긴다. 기본 클래스의 소멸자만 호출되므로 동적 할당된 메모리가 완전히 해제되지 않는다. 가상 소멸자 // Animal.hpp class Animal { public: virtual ~Animal(); pri..
다형성 사전 지식 멤버 함수 멤버 함수는 어디에 있는가? 멤버 함수는 클래스의 코드 섹션에 위치하며, 모든 클래스 객체가 공유한다. 각 개체마다 멤버 함수의 메모리가 잡혀있는가? myCat->getName(); // "Coco" yourCat->getName(); // "Mocha" 함수의 동작은 완전히 일치하며, 매개변수로 받아도 된다. 저수준에서는 멤버 함수는 전역 함수와 크게 다르지 않다. 컴파일 시에 딱 한 번 메모리에 할당된다 (code section). 함수 오버라이딩 덮어쓰기 함수 정의가 같지만, 구현이 각 클래스마다 다른 것. 정적 바인딩 - 멤버 변수 선언된 클래스에 따라서 접근하는 코드 섹션을 구분한다. 동적 바인딩 - 가상 멤버 함수 // Animal.hpp class Animal {..
상속 예제 // Animal.hpp class Animal { public: Animal(int age); ~Animal(); // 소멸자 추가 private: int mAge; }; // Cat.hpp class Cat : public Animal { public: Cat(int age, const char* name); ~Cat(); // 소멸자 추가 private: char* mName; }; // Cat.cpp Cat::Cat(int age, const char* name) : Animal(age) { size_t size = strlen(name) + 1; mName = new char[size]; strcpy(mName, name); } Cat::~Cat() { delete[] mName; /..
const를 사용하는 이유 멤버 변수의 값이 바뀌는 것을 방지한다. 객체가 상수화되어 있으면 해당 객체의 멤버 변수를 변경할 수 없으므로 안전성을 제공한다. 최대한 많은 곳에 const를 붙여야 한다. 코드를 읽는 사람에게 해당 변수나 함수의 의도를 명확히 전달하고, 컴파일러에게 잠재적인 오류를 찾아내도록 돕는다. Local 변수에도 그렇게 해야한다. 함수 내에서 값이 변경되지 않는 변수에 const를 사용하면 함수의 의도를 명확히 하고, 컴파일러가 불필요한 변경을 방지할 수 있다. Vector를 더하는 a + b의 경우 Vector operator+(const Vector& rhs) const; a와 b Vector는 더하려는 값일 뿐 변해서는 안된다. 연산자 오버로딩과 const Vector oper..
연산자 함수처럼 작동하는 부호 int result = num1 + num2; if (num1 < num2) {} if (IsNumber() || IsAlph()) {} num1++; num1 += 1; 연산자의 종류 단항 연산자 ! & ~ * + ++ - -- 변환 연산자 등 if (!IsNumber()) {} Vector& vRef = vector1; // 레퍼런스는 단항 연산자가 아니다. int hexNum = 0xFF00; int inversion = ~hexNum; int *number1 = &number; // 주소를 불러오는 건 단항 연산자이다. *number1 = 10; int number2 = +10; int number3 = -10; ++num1; num1--; --num1; num1--..