본문 바로가기

Contact English

【C++】 3강. OOP 1부

 

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& otherclass_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. classfriend를 부여하는 경우 

friendpublic으로 쓰든 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::getfriend를 부여했으므로 Level::getprivate member variable인 window에 접근할 수 있음

② 위와 같이 쓰려면 WindowLevel::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;
}

 

friendpublic에 있든 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