VEDA 10일차 - C++
객체지향 특성
- 추상화 : 불필요한 부분을 배제하고 공통된 특징을 추출
- 캡슐화 : 변수와 함수를 클래스로 감싸서 은닉, 불필요한 정보 노출 방지
- 상속성 : 부모 객체의 특성을 이어받을 수 있음
- 다형성 : 상속 관계의 객체에서 같은 기능이 다르게 동가할 수 있는 특성
constructor : 객체가 생성된 직후에 자동으로 호출되는 함수, 여러 후보군들을 둘 수 있다. (단 default constructor는 후보 constructor가 없을 때나 추가됨)
destructor : 객체가 해제되기 바로 직전에 자동으로 호출되는 함수
접근제어
- private : 클래스 내부에서만 접근 가능(default)
- protected : 상속받는 클래까지 접근 가능
- public : 접근에 제한이 없음
struct와 class의 차이 : struct는 default가 public, class는 default가 private
constructor는 initializer list를 제공한다.
static 맴버를 이용하면 클래스를 전체에 대해서 관리할 수 있다. ex) static int count를 사용하여 특정 클래스 개수를 관리할 수 있다.
클래스에 선언한 정적 변수는 전역 범위에서 초기화해야 한다. const 변수는 생성자에서 정의***
copy constructor는 default constructor이다. 만약 정의되어 있지 않았다면 default로 넣어준다.
deep copy : value를 copy -> 동적 메모리 할당시 사용할 필요가 있다.(안그러면 객체가 소멸되기 전에 맴버 변수의 메모리가 해제될 수 있다.)
shallow copy : address만 연결
This 포인터 : 클래스 내부에서 클래스가 몇 번지 메모리에 저장되었는 지 알려준다. 자기 자신을 가리키는 포인터
-> 맴버 함수 체이닝을 구현할 때 사용, 객체가 객체를 반환하고 그 객체가 다시 맴버 함수를 실행시키는 방식 -> 코드를 간결하게 만들고 호출 순서를 직관적으로 표현할 수 있음.
XX& add(int i) {
xx += i;
cout << xx << ' ';
return *this;
};
XX(0).add(1).add(1).add(1).add(1).add(1); // 1 2 3 4 5 출력
constructor() : var1(a), var2(b);
#include <iostream>
using namespace std;
class X {
int x;
public:
X() : x(100) {
cout << "constructor" << endl;
};
X(int x) : x(x) {
cout << "constructor" << endl;
};
~X() {
cout << "destructor" << endl;
};
int get_x(void);
};
class XX : public X {
int xx;
public:
XX() {
cout << "void XX constructor" << endl;
}; //기본 생성자
XX(int xx) : xx(xx), X(xx + 30) /* - 부모 정의 법 */ {
cout << "void XX constructor" << endl;
}; //매개 변수로 받는 법
explicit /*용법 제한*/ XX(const XX& rhs /*원본을 그대로 준다.*/) {
xx = rhs.xx; //같은 클래스 끼리는 바로 찍을 수 있다.
count += 1; //이게 불림
} //카피
~XX() {
cout << "void XX destructor" << endl;
}
int get_xx();
};
int X::get_x(void) {
return this->x;
}
int XX::get_xx(void) {
return this->xx;
}
int main() {
XX xx = XX(200);
cout << "X is " << xx.get_x() << endl;
cout << "XX is " << xx.get_xx() << endl;
return 0;
}
상속성과 다형성
상속성 : 클래스를 만들 때 다른 클래스의 멤버 함수, 멤버 변수를 물려받는 것
부모 클래스, 기본 클래스, 슈퍼 클래스 <-> 자식 클래스, 파생 클래스, 하위 클래스
자식 클래스는 부모 클래스가 생성되고 난 후 자식 클래스가 생성된다.
자식 클래스는 자식 클래스가 해제된 후, 부모 클래스가 해제된다.
함수와 연산자 오버로딩
오버로딩 : 추가, 함수명 또는 연산자 형태가 같아도 리턴값, 파라미터 값이 다르면 다른 함수 취급을 한다.
using namespace std;
int func() { return 0; };
int func(int x) { return 1; };
int func(int x, int y) { return 2; };
//default 문 사용시 오버로딩이 안된다.(컴파일러 에러)
int main() {
cout << func() << endl;
cout << func(1) << endl;
cout << func(1, 1) << endl;
return 0;
}
오버라이딩 : 덮어쓰기, 자식 클래스에 부모 클래스와 같은 이름의 메서드를 재정의할 수 있다. (하위 클래스 우선 순위)
using namespace std;
class Parent {
int result;
public:
int func() { return 0; };
};
class Child : public Parent {
int result;
public:
int func(){ return 1; };
};
int main() {
cout << Parent().func() << endl;
cout << Child().func() << endl;
return 0;
}
Class1.operator+(Class2);
Class& opeartor+(const Class& rhs){
XX temp;
temp.xx = xx + rhs.xx;
return temp;
}
접근 지정자와 프렌드
- public : 외부에서 참조 가능
- protected : 같은 클래스 내부 또는 자식 클래스까지 참조 가능
- private : 같은 클래스 내부에서만 참조 가능
-----------------------------------------------------------------------------------------------------------------------------------------------------------
- class XX : private x : 부모 class private -> 참조 불가, 부모 class protected -> private, 부모 class public -> private
- class XX : protected x : 부모 class private -> 참조 불가, 부모 class protected -> protected, 부모 class public-> protected
- class XX : public x : 부모 class private -> 참조 불가, 부모 class protected -> protected, 부모 class public -> public
freind class와 friend 함수
freind class로 선언된 클래스는 friend로 정의된 함수를 참조할 수 있다.(설사 private 영역에 정의되어 있더라도!)