3 분 소요

Class란?

class Triangle{
		double sideA;
		double sideB;
		double sideC;
	public:
		double perimeter();
}

double Trangle::perimeter(){    // object의 reference point가 자동으로 넘어감 
	return sideA + sideB + sideC;  // 따라서 class 속 변수들 바로 사용 가능
}

int main(void){
	Triangle t1;
	double p1;
	p1 = t1.perimeter()
}
  • C의 structure의 확장 버전
    • var 뿐만 아니라 행동(function)까지 포함하여 object로 사용
    • hierarchy(계층화된) programming 가능
    • well-defined interfaces
  • object의 blueprint(설계도)
    • class로 생성한 실체가 object

Access Specifier

class에서 변수와 메소드 정의 시, 적근 가능 범위 설정

  • private(default) : 해당 클래스의 method에서만 호출 가능
  • protected : 해당 클래스 혹은 이를 상속한 subclass에서만 호출 가능
  • public : anywhere : 클래스 밖(ex main 함수)에서도 호출 가능

Member : Variable & Method

  • class의 member는 크게 variable과 method로 나눌 수 있다.
  • methods : Class의 Member인 function
    • method는 클래스 이름과 붙어서 사용된다.
      • 선언문에서 : 클래스이름::method이름()
      • 일반 object 속 함수 호출 : 클래스이름.method이름()
      • pointer object 속 함수 호출 : 클래스이름→method이름()

Special Variable : Static Members

  • 상수
  • static member는 class안에선 선언만 하고, 값 지정은 class 밖에서 해야한다.
  • static memebr는 object에서 따로 선언하지 않아도 사용 가능하다.
  • static memebr는 class 이름으로 바로 사용할 수 있다.
class Dummy{
	static int n;  //class안에선 선언만
};

int Dummy::n=0; //값 지정은 class 밖에서 해야한다.

int main(){
	Dummy a;
	cout << a.n << '\n';  //static memebr는 object에서 따로 선언하지 않아도 사용 가능하다.
	cout << Dummy::n << '\n';  //static memebr는 class 이름으로 바로 사용할 수 있다.
}

Special Methods : Constructor/Destructor

image

  • 사전 지식 : lvalue, rvalue
    • Lvalue : 이름이 있는 object. Copy/Move 이후에도 접근 가능, &로 참조
    • Rvalue : 이름이 없는 object. Copy/Move 이후 접근 불가. &&로 참조

        vector<int> a = {1,2,3,4,5};
        vector<int> b = a;
        // a, b는 lvalue, {1,2,3,4,5}는 rvalue
      
    • std::move(a);
      • Lvalue a를 Rvalue로 바꾸기
      • 이후 더 이상 a가 필요없을 때만 사용

a. Constructor

  • object 만들 때 자동 호출되는 특수 method로, constructor를 통해 object를 생성한다.
  • class와 같은 이름을 가진다.
  • 아무것도 return하지 않고, return type도 지정하지 않는다.
Triangle::Triangle(double a, double b, double c){
	sideA = a;
	sideB = b;
	sideC = c;
}

Triangle t1(2.0, 2.0, 3.0); //static 선언
  • initialization list
    • constructor의 {} 속 내용이 실행되기 이전에 수행되는 리스트
    • 상속에서 유용하게 쓰인다.
      TTriangle::Triangle(double a, double b, double c)
      	: sideA(a), sideB(b) {             // side = A, side = B와 동일
      	sideC = c;
      }
    
  • Default Constructor
    • argument 없이 initialize하는 constructor
    • 따로 constructor 정의 안 할 경우, 자동 생성
      • 하나라도 다른 constructor를 선언할 경우, 자동 생성되지 않음
      • 둘 다 쓰고 싶으면 overload되게 둘 다 써야함.

b. Destructor

  • object 없어지기 직전에 자동으로 호출되는 특수 method
  • class이름에 tilde(~)를 붙이고, argument는 없다.
~Triangle(void)
  • Default Destructor
    • no argument, no return
    • 따로 Destructor 정의 안 할 경우, 자동 생성
    • 클래스가 끝날 때, 그 클래스에 해당하는 모든 메모리를 비운다.
      • member 중 클래스가 있으면 그 클래스의 destructor도 호출된다.
    • 주로 pointer가 존재할 때, 사용자가 따로 선언할 필요가 생긴다.
      • 포인터를 지우더라도 포인터가 가리키고 있는 주소의 값은 남기 때문이다.

c. Copy Constructor

  • argument로 자신과 동일한 class의 object를 받는 constructor
  • 들어온 object의 모든 내용을 복제한다
  • 양쪽 object 모두 lvalue
  • Default Copy Constructor

      class Example5{
      	Example5(const Example5& x){};
      }
      Example5 foo;
      Example5 bar = foo;
    
    • shallow copy가 일어난다.
      • 단순히 value를 복사
      • 문제점 : pointer를 복사 시, 동일한 주소를 두 object의 pointer가 모두 가리키게 되서 문제가 될 수 있다.
  • Copy Constructor 선언
    • Deep Copy를 하도록 선언할 수 있다.
      • Deep Copy ↔ shallow copy
        Example5(const Example5& x) : ptr(new string(x.content())) {};
        Example5(const Example5& x) {ptr = new string(x.content())};
      

d. Copy Assignment

  • Copy Constructor가 있어서 수행할 수 있다.
  • Copy Constructor vs Copy Assignment 차이
    • Copy Constructor : 새로 object를 생성하면서 기존 object의 constructor와 값을 복사
    • Copy Assignmnet : 두 object 실체가 있을 때, 한쪽의 값들을 복사
      MyClass foo;
      MyClass bar;
      foo = bar;
    
  • Operator Overloading이 가능해지는 원리이기도 하다.

e. Move Constructor/Move Assignment

  • Copy Constructor/Assignmnet와 유사하되, 오른쪽이 rvalue(unnamed obejct)
  • 실행된 이후엔 오른쪽 object는 사라진다.
  • 대표적 예 : function의 return 값이 object이면, return 했을 때 이름이 없다.
MyClass fn();
MyClass bar = fn();  // Move Constructor
bar = MyClass();     //Move Assignment
  • 선언 : Copy와 같은 구조이되, &가 2개가 되면 Move Constructor이다.
//deflaut move constructor
MyClass (MyClass && x); // argument로 들어온기존 object를 변형(비우기) 할 것이므로 const는 붙이지 않는 것으로 보임.

//선언
// move constructor
Example6 (Example6&& x) : ptr(x.ptr) {
	x.ptr=nullptr;
};

// move assignment
Example6& operator= (Example6&& x) {
	delete ptr;       // pointer를 포함하는 new[] object를 assignment 할 때 한해서 필요 (아니어도 있어서 문제될 건 없음) 
	ptr = x.ptr;
	x.ptr=nullptr;     // move이니 기존 것 삭제
	return *this;
};
  • 장점 : Dynamic memory allocation의 경우, 단순히 pointer를 복사하는 것으로 수행할 수 있다.
    • Cost가 큰 Copy를 수행하지 않아도 된다.
    • 이는 argument를 call-by-value 대신 call-by-reference를 할 때의 장점과 같다.

태그:

카테고리:

업데이트: