전체 글
189C++ 멤버 함수(생성자, 파괴자, 연산자 오버로딩 등)의 특성(표로 요약)
함수 상속 멤버 또는 프렌드 디폴트로 생성 가상으로 선언 리턴형 생성자 X 멤버 O X X 파괴자 X 멤버 O O X = X 멤버 O O O & O 둘 중 하나 O O O 변환 O 멤버 X O X () O 멤버 X O O [] O 멤버 X O O -> O 멤버 X O O op= O 둘 중 하나 X O O new O static 멤버 X X void * delete O static 멤버 X X void 기타 연산자 O 둘 중 하나 X O O 기타 멤버 O 멤버 X O O 프렌드 X 프렌드 X X O op=는 +=,*=와같은 복합 대입 연산자들을 말합니다.
프로그래밍/C++ 2019.10.24 PlorenceC++ 추상화 기초 클래스(abstract base class; ABC)와 순수 가상 함수(pure virtual function)
추상화 기초 클래스(abstract base class) 추상화 기초 클래스는 기초 클래스로 쓰이고 순수 가상 함수가 1개 이상의 클래스를 추상화 기초 클래스라고 부릅니다. 줄여서 ABC라고 부르기도 합니다. 그리고 이 추상화 기초 클래스의 모든 멤버 함수가 순수 가상 함수일 때 인터페이스(Interface)라고 부릅니다. 이러한 추상화 기초 클래스를 상속받는 클래스를 구체화 클래스(concrete class)라고 부릅니다. 추상화 기초 클래스는 기초 클래스로부터 상속받는 여러가지 클래스가 있을 때, 공통적인걸 하나로 묶는 클래스입니다. 하나로 묶으면서 파생 클래스마다 다른 동작을 해야하는건 순수 가상 함수로 선언을 합니다. "대충 이런일은 할 건데 이 행동은 파생 클래스마다 다를 거니까 설계만 해놓았어..
프로그래밍/C++ 2019.10.22 PlorenceC++ 접근 제어자 - protected
protected는 public과 private특징을 섞었습니다. 멤버 변수에 protected를 지정하면 파생 클래스에서는 public처럼 접근이 가능하지만 객체에서는 직접 접근이 불가능합니다. #include using namespace std; class Person { private: int stat; protected: int power; public: virtual void Show(int A) { cout
프로그래밍/C++ 2019.10.22 PlorenceC++ 가상 함수의 동작 원리
C++는 가상 함수들이 어떻게 동작해야 하는지 규정하고 있고 그 구현은 컴파일러 개발자의 몫입니다. 구현된 방법을 알면 가상 함수의 개념을 좀 더 잘 이해할 수 있습니다. 컴파일러는 가상 함수를 어떻게 처리하는가? 먼저 각각의 객체에 숨겨진 멤버를 하나씩 추가합니다. 숨겨진 멤버는 함수의 주소들로 이루어진 배열을 지시하는 포인터를 저장합니다. 일반적으로 그 배열을 가상 함수 테이블(VirTual Function Table, 줄여서 vtbl)이라고 합니다. vtbl에는 클래스의 객체들을 위해 선언된 가상 함수들의 주소가 저장되어 있습니다. 기초 클래스의 한 객체는 그 클래스를 위한 모든 가상 함수들의 주소로 이루어진 테이블을 지시하는 포인터를 가집니다. 파생 클래스도 가상 함수들의 주소로 이루어진 별개의 ..
프로그래밍/C++ 2019.10.22 PlorenceC++ 정적 결합(Static Binding)과 동적 결합(Dynamic Binding)
프로그램이 함수를 호출할 때 실행 코드의 어느 블록이 사용되는지에 대한 대답은 컴파일러에게 있습니다. 먼저 소스 코드에 있는 함수 호출을 특정 블록에 있는 함수 코드를 실행하라는 뜻으로 해석하는 것을 "함수 이름을 결합(binding)이라고 합니다. C언어에서는 각각의 함수가 별개의 함수에 해당하기 때문에 이 작업이 간단하지만(함수 오버 로딩이 없음.) C++에서는 함수 오버 로딩 때문에 이 작업이 조금 복잡합니다. 이 결합은 컴파일 타임에 이루어지고 이 결합을 정적 결합(static binding)또는 초기 결합(early binding)이라고 합니다. 하지만 가상 멤버 함수(virtual 키워드가 달린)들은 프로그램이 실행할 때 사용자가 객체를 결정하기 때문에 컴파일 타임에는 진행할 수 없습니다. 그..
프로그래밍/C++ 2019.10.22 PlorenceC++ 가상 파괴자(virtual destructor)의 필요성
일반적으로 파괴자에서 처리해야 할 작업이 없으면 파괴자 정의 자체를 안 하는 경우가 많습니다. 할당한 걸 해제해줘야 하는 경우 파괴자를 정의하고 처리해줘야 하는 게 정상입니다. 가상 파괴자는 다음과 같은 상황일때 필요합니다. 기초, 파생 클래스에서 파괴자를 정의 한경우에 (필요로 할 때) 업 캐스팅될 여지가 있는 경우에 가상 파괴자가 아닐 때 #include using namespace std; class Person { public: ~Person() { cout
프로그래밍/C++ 2019.10.18 PlorenceC++ 다형(polymorhphic)과 가상 멤버 함수(virtual member function)
다형 파생 클래스에 대해 하는 행동이 기초 클래스에 대해 하는 행동과 다른 멤버 함수가 요구되는 상황이 있을 것입니다.(호출하는 객체에 따라 행동이 달라짐.) 즉 호출하는 객체에 따라 멤버 함수의 행동이 달라질 수 있습니다. 처한 상황에 따라 멤버 함수가 여러 가지 다른 행동을 할 수 있기 때문에, 여러 가지 형식을 가지고 있다는 의미에서 그러한 복잡한 행동을 다형이라고 부릅니다. 가상 멤버 함수(virtual method) 먼저 기초 클래스의 멤버 함수를 파생 클래스에서 재정의 하는 방법은 virtual 키워드를 사용하는 것입니다. 재정의할 때는 함수 시그니처가 동일해야 합니다. 간단한 예시를 들어보면 Person이라는 클래스를 정의하고 각각 Man, Girl이라는 클래스도 정의 후에 이 클래스는 Pe..
프로그래밍/C++ 2019.10.18 PlorenceC++ is-a 관계와 has-a 관계
is-a 관계 is-a 관계는 파생 클래스에 있어서 상속의 조건인데 is-a 관계의 의미인 ~은 ~이다라는 관계를 성립하자는 것입니다. public 상속을 사용할 때는 is-a관계가 성립되도록 만들어야 합니다. 예를 들어서 "사과는 과일이다"은 성립합니다. 사과는 과일이니까요. 틀린 예로 "과일은 사과이다."가 있겠습니다. 문장 그대로 과일이라는 단어는 사과를 의미하지 않으니까요. 그래서 Apple 클래스는 파생클래스로 Fruit 클래스를 상속할 수 있는 것입니다. is-a관계여야만 하는 이유 여러가지 과일의 대한 클래스를 만들 때, 기본적으로 그 사과들이 가지고 있는 공통적인 특징을 추상화한 클래스가 기초 클래스고 상속받은 여러가지 과일 클래스가 파생 클래스입니다. 이처럼 범위가 좁아지면서 기능이 기초..
프로그래밍/C++ 2019.10.18 PlorenceC++ 클래스 상속(class inheritance)
C++는 클래스를 확장하고 수정하기 위해 단순한 코드 수정보다 더 강력한 수단을 제공합니다. 바로 클래스 상속입니다. 기초 클래스(base class)라 부르는 클래스로부터 모든 멤버 함수와 멤버들을 상속받고 새로운 파생 클래스(clerived class)를 만들 수 있게 합니다. 상속으로 할 수 있는 일 기존의 클래스에 기능을 추가할 수 있습니다. 클래스가 나타내고 있는 데이터에 다른 것을 더 추가할 수 있습니다. 클래스 멤버 함수가 동작하는 방식을 변경할 수 있습니다. 상속의 의미 어떤클래스를 다른 클래스로부터 상속할 때, 오리지널 클래스를 기초 클래스(base class)라 하고 상속받는 클래스를 파생 클래스(derived class)라고 합니다. 위에서도 언급했지만 상속받게되면 멤버, 멤버 함수에..
프로그래밍/C++ 2019.10.18 PlorenceC++ 멤버 초기자 리스트(member initializer list)
C++에서는 상수인 클래스 멤버를 초기화시키기 위하여 특별한 문법을 제공합니다. 문제 상황 및 해결 일반적으로 상수인 클래스 멤버를 생성자를 통하여 초기화시키지 못합니다. 그래서 생성자의 코드 실행전인 객체가 생성될 때 초기화해야 합니다. #include class Person { const int age; Person(int p_age) { age = p_age; //허용안됨 } }; int main(void) { } 위에 방법으로는 상수인 클래스 멤버를 초기화할 수 없습니다. 그래서 나온게 멤버 초기자 리스트입니다. #include class Person { const int age; Person(int p_age) : age(p_age){//허용됨 } }; int main(void) { } 위와 같..
프로그래밍/C++ 2019.10.17 PlorenceC++ new 연산자와 delete 연산자
new, delete연산자는 동적 할당과 해제에 연관되어 있으며 C++에서 제공하는 방법입니다. C언어에서는 malloc함수와 free함수를 통해서 동적 할당과 해제가 가능했었습니다. 동적 할당의 필요성 동적 할당은 미리 할당할 필요도 없으며, 원하는 크기를 정확히 할당이 가능하므로 쓸모없는 크기를 잡아먹지 않게 됩니다. 만약 계속 문자열을 입력받고 계산해야하는데 입력받은 문자열의 크기는 10~10000이라고 가정합시다. 동적 할당을 하지 않을 경우 정적 할당(지역변수)으로 최대 문자열의 크기인 10000을 잡고 미리 할당해야 합니다.(이런 경우 입력 문자열이 10이라면 필요 없는 메모리 공간이 9990이나 됩니다.) 하지만 동적할당은 입력받은 문자열의 크기를 구해서, 그 크기만큼 동적 할당하게 되면 필..
프로그래밍/C++ 2019.10.17 PlorenceC++ 복사 생성자(Copy Constructor)
복사 생성자는 어떤 객체를 새로 생성되는 객체에 복사하는 데 사용됩니다. 복사 생성자는 일반적인 대입에 사용되는 것이 아니라 값 전달에 의한 함수 매개변수 전달을 포함한 초기화 작업에 사용됩니다. 복사 생성자의 원형 ClassName(const ClassName &); 복사 생성자의 호출 시기 복사 생성자는 새로운 객체가 생성되어 같은 종류의 기존 객체로 초기화될 때마다 호출됩니다. 복사 생성자의 호출 시기는 아래의 코드와 같습니다. Person Carl(); Person Plorence(Carl); //복사 생성자 호출 Person Plorence =Carl; //복사 생성자 호출 Person Plorence = Person(Carl); //복사 생성자 호출 Person * Plorence = new ..
프로그래밍/C++ 2019.10.17 Plorence