3강. 객체지향프로그래밍(OOP)
추천글 : 【C++】 C++ 목차
1. class [본문]
2. 생성자 [본문]
3. 소멸자 [본문]
4. assignment operator [본문]
5. static [본문]
6. struct [본문]
7. nested class [본문]
8. friend [본문]
a. GitHub
1. class [목차]
⑴ 문법 : 반드시 ;로 끝나야 함
class class_name {
access_specifier :
member1;
access_specifier :
member2;
...
};
⑵ 접근 제어자(access specifier) : member에만 적용. java처럼 class에 적용될 수 없음
class className {
// default members
public:
// public members
protected:
// protected members
private:
// private members
};
① public : 어디에서든 접근할 수 있음
② protected : same class 또는 subclass 또는 friends로부터 접근할 수 있음
③ private : same class 또는 friends로부터 접근할 수 있음
④ default : private과 동일함
⑤ (참고) .h 파일 내의 private 변수는 동일한 이름의 .cpp 파일에서도 접근할 수 있음
⑶ member function은 class 내에서 정의되거나 class 밖에서 :: 연산자를 통해 정의될 수 있음
2. 생성자(constructor) [목차]
⑴ 기본 문법
class class_name {
public:
class_name(): member_initializer_list {
// Constructor Body
}
};
① .h 파일에서 이루어짐
② semi-colon(;)은 안 써도 되는 듯
③ 일반적으로 public으로 선언됨
○ java에서도 제한된 경우에 public으로 선언되지 않기도 함
④ procedural programming의 예외
○ 생성자 내에서 사용되는 변수가 생성자 이후에 나와도 됨
○ (주석) 생성자이므로 OOP가 적용되지 procedural programming이 적용되지 않는 듯
⑤ MyClass myClass;만 해도 생성자가 자동으로 호출됨
⑵ 선언
Rectangle rect1 (3, 4);
// stored in stack
// not pointer variable
Rectangle* rect2 = new Rectangle(3, 4)
// stored in heap
// pointer variable
⑶ 초기화
① .cpp 파일에서 이루어짐
② 방법 1. initialization in constructor body
class X {
public:
int a, b, i, j;
X(int i) {
b = i;
this -> i = i-1;
j = this -> i;
}
}
③ 방법 2. default initializer
④ 방법 3. member initializer list : 반드시 { }를 뒤에 쓰지 않아도 됨
class Y {
public:
int a, b, i, j;
Y(int i) : b(i), i(i-1), j(this -> i) { }
}
⑷ constructor overloading : 파라미터 조합을 달리 하는 여러 constructor를 정의할 수 있는 것
⑸ (출제 예상) copy constructor (↔ convert constructor)
// syntax of copy constructor
class class_name {
class_name (const class_name& other) {
// Copy Constructor Body
}
}
① 개요
○ 정의 : constructor 중에서 parameter로 자기 자신과 같은 object의 pointer를 가지는 특수한 경우
○ java에는 모든 게 reference이지만 C++은 아예 배려를 해줘서 새로운 객체를 만들어 줌
② copy의 의미
○ implicit copy constructor : shallow copy라고도 함
○ 정의 : class 내에 pointer member가 있으면 다른 객체와 동일한 주소를 할당하는 것
○ 메모리를 공유하므로 문제가 발생할 수 있음
○ (주석) 객체 정보를 일일히 살펴보지 않고 대충 주소만 저장하고 끝낸 점에서 shallow하다고 표현한 듯
○ (참고) 그 주소에 저장된 데이터가 변하면 shallow copy를 한 class도 영향을 받는다는 치명적인 단점이 있음
○ explicit copy constructor : deep copy라고도 함
○ 정의 : class 내에 pointer member가 있으면 새로운 메모리를 할당하는 것
○ 대체로 포인터 변수를 ember 변수로 가지는 경우 deep copy 기능으로 구현하도록 권장됨
③ &의 의미 : 기본적으로 call by reference
④ const의 의미
○ 파라미터에 해당하는 객체의 member를 바꾸지 않겠다고 하는 것
○ const를 안 쓴다고 copy constructor가 되지 않는 것은 아님
○ const class_name& other와 class_name& other를 갖는 두 copy constructor : 옛날 버전이었으면 compile error
C++ multiple copy constructors specified (ref)
⑥ 예 1. initialization
○ 예 1-1. T a = b;
○ 예 1-2. T a(b);
○ 예 1-3. Movie *mm = &movie; // Movie m(another_movie);
○ 예 1-4. Movie m = *(&(movie));
○ 단, b는 T class의 객체
⑦ 예 2. function argument passing by value
○ f(a);
○ 단, a는 T class의 객체, f는 void f(T t)와 같이 정의
○ 즉, 함수 인자로 class를 넘길 때 포인터로 넘겨주지 않으면 copy constructor가 자동으로 호출됨
⑧ 예 3. function return by value
○ return a;
○ 단, a는 T class의 객체, f는 T f()와 같이 정의
○ 즉, return value로 class를 반환할 때 copy constructor가 자동으로 호출됨
⑹ move constructor
3. 소멸자(destructor) : ~로 표시함 [목차]
⑴ 정의 : 객체가 소멸될 때 자동으로 실행되도록 한 코드
⑵ (참고) java의 경우 : garbage collector가 있어서 더 이상 쓰지 않는 객체를 알아서 제거함. 소멸자 개념은 없음
⑶ C++에서 stack에 정의된 객체
① nested loop를 벗어나거나 프로그램이 끝나면 destructor를 calling하고 객체는 소멸함
⑷ C++에서 heap에 정의된 객체
① (참고) C++에서 new라는 명령어를 이용해 생성된 변수 또는 객체는 heap에 저장됨
② delete라는 명령어를 이용하거나 프로그램이 끝나면 객체는 소멸함
③ 오직 delete라는 명령어를 이용하는 경우에만 destructor를 calling함
④ delete로 객체를 소멸시켜야 하는 이유 : heap에서의 memory leak을 방지하기 위함
⑤ memory leak handling이 중요한 이유 : 서버와 같이 상시 작동 프로그램에서 다운을 일으키는 주된 이유
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
⑸ 소멸자의 호출은 생성자의 호출과 반대 순서로 일어남
① 예 : A, B 순으로 객체가 생성됐고 동시에 소멸되면 ~B, ~A 순으로 소멸자가 호출됨
② 이유 : constructor의 자료구조는 stack에 쌓이는 구조이기 때문
4. assignment operator [목차]
⑴ copy assignment operator
#include <iostream>
class Test {
public:
Test() { }
Test(const Test &t) {
std::cout << "CopyCon" << std::endl;
}
Test& operator= (const Test &t){
std::cout << "Assign" << std::endl;
return *this;
}
}
int main() {
Test t1, t2;
t2 = t1; // "Assign"
Test t3 = t1; // "CopyCon"
Test t4(t1); // "CopyCon"
return 0;
}
① copy constructor는 최초에 인스턴스를 정의할 때 호출됨
② copy assignment operator 안에 copy constructor를 사용하는 것은 불가능
○ 이유 : 이미 생성된 object를 가지고 연산하는 것이기 때문
③ (주석) operator=을 하나의 method name처럼 이해해도 됨
④ (참고) return *this;
○ t3 = t2 = t1;과 같은 연산을 가능하게 하기 위함
○ 즉, t3.operator=(t2.operator=(t1));을 가능하게 하기 위함
⑵ move assignment operator
5. static [목차]
⑴ 개요
① 정의 : member variable 또는 function을 class instance에 bound하는 게 아니라 class 자체에 bound시키는 것
② static이라는 keyword는 class 내부에서만 쓸 수 있음
⑵ static function
① this 등 instance member가 사용될 수 없음
⑶ static variable
① access modifier에 관계없이 global scope에서 초기화할 수 있음
② class 내부에서 초기화시킬 수 없음
○ 일반적으로 global scope에서 초기화시킴
○ (참고) java에서 class 내 static variable 초기화가 가능함
③ function 내부에서 초기화시킬 수 없음
○ 예를 들어, main function 내부에서 초기화시킬 수 없음
④ instance가 static variable의 값을 바꾸는 것은 가능함
⑤ const static variable : instance class 내부에서도 정의할 수 있음
const static int MAX_WORKERS = 2;
6. struct [목차]
⑴ 누구에게나 접근 가능한 변수들의 집합 : member function은 존재하지 않음
⑵ access 수준이 무조건 public이기 때문에 안전하지 않음
⑶ 역사적으로 C에서의 struct를 계승한 것
⑷ 초기화
#include <iostream>
struct Point { int x = 3, y, z; };
int main() {
Point p, q { 1, 2 }, r { .z = 4 };
}
7. nested class [목차]
⑴ 한 class 안에 있는 또다른 class
⑵ access modifier는 다양할 수 있음 : java에서는 무조건 private
8. friend [목차]
⑴ 개요
① 정의 : non-member function이나 다른 class에게 private 또는 protected member의 지위를 부여하는 것
② 많이 안 쓰는 것을 권장하지만 많은 이들이 사용하고 있음
⑵ 경우 1. class에 friend를 부여하는 경우
① friend를 public으로 쓰든 private으로 쓰든 아무 차이가 없음 (ref)
class A{
public:
friend class B;
};
class A{
private: //or nothing as the default is private
friend class B;
};
② 위 예제에서 B class는 A class의 어떤 member든 접근할 수 있음
③ friend는 reciprocal하지 않기 때문에 A class가 B class의 어떤 member든 접근할 수 있는 건 아님
⑶ 경우 2. function에 friend를 부여하는 경우 - 다른 class의 함수
class Window{
friend int Level::get(Window& w);
int window;
public:
Window(void): window(2) {}
void show(void);
};
int Level::get(Window& w){
return w.window + level;
}
① Level::get에 friend를 부여했으므로 Level::get은 private member variable인 window에 접근할 수 있음
② 위와 같이 쓰려면 Window는 Level::get에 접근할 수 있어야 함 : 접근할 수 없으면 invisible함 (ref)
⑷ 경우 3. function friend를 부여하는 경우 - global function (ref)
class Program{
public:
friend void display();
};
Program::input(){
std::cout << "Hello" << std::endl;
}
int main(){
display();
return 0;
}
① friend가 public에 있든 private에 있든 정상적으로 작동함
입력: 2020.11.21 17:59
'▶ 자연과학 > ▷ C, C++' 카테고리의 다른 글
【C++】 C++ 목차 (0) | 2020.12.01 |
---|---|
【C++】 4강. OOP 2부 (0) | 2020.12.01 |
【C++】 2강. 포인터 (0) | 2020.11.21 |
【C++】 1강. C++ 시작하기 (0) | 2020.11.18 |
【코딩】 C 언어로 이항계수 (0) | 2016.06.27 |
최근댓글