1. const
객체를 const 로 정의하는 것은 변수 앞에서 const 를 적어주기만 하면 된다.
const int a;
그러면 상수처리가 되어 이 값을 바꿀 수 없다.
그런데 포인터와 연관되면 순서가 헷갈린다.
int* const a = 1;
const int* a = 1;
공통점은 모두 자료형 다음에 포인터가 온다는 것.
차이는 전자는 주소값이 바뀌지 않는다는 것, 후자는 값 자체가 바뀌지 않는다는 것이다.
const int* const a = 1;
처럼 둘 다 쓸 수 있다.
이는 const 의 위치를 염두에 두고 외워야한다.
a 앞에 const 는 주소값이 저장되는 a 자체를 상수로,
const int * 인 경우 포인터가 있으니까 포인터가 가르키는 값 자체를 상수로.
레퍼런스와 연관된 경우 경우의 수는 하나 뿐이다.
const int& a = b;
상수처리된 레퍼런스는 const 멤버 함수만 쓸 수 있다는 것에 주의하자.
함수인 경우
int Func() const { return nNum};
이렇게 해서 상수화 시킬 수 있다.
그 기능은 멤버 변수를 바꿀 수 없다는 것.
상수화 되지 않은 함수를 사용할 수 없다는 것. 물론 포인터를 사용해서 바꿀 수는 있다.
포인터를 리턴할 수 없다는 것.
그리고 중요한 것은 상수화된 클래스 객체는 상수화된 멤버 함수만을 사용할 수 있다는 것이다.
또한 상수화된 함수와 안된 함수는 다른 함수로 취급된다. 즉 오버라이딩 된다는 것.
2. Explicit :
함수에서 파라미터의 자동 형변환을 막아줌
3. Virtual:
함수에 적용되는데 vritual function 은 동적할당을 하거나 할때 포인터의 자료형이 아니라 객체의 자료형의 함수를 사용하기 위해 사용된다. - 함수의 Polymophism 을 지원하기 위해 도입되었다.
virtual 을 오버라이딩 하려면 오버라이딩 되는 함수도 virtual 이어야 한다.
virtual 함수에 = 0 을 하면 순수 가상함수가 되며, 객체로 만들 수 없게 되어 추상 클래스가 된다. 다만 상속할 클래스를 넣을 수는 있다.
가상 함수가 오버라이딩 되거나 오버라이딩을 하면 가상 함수 테이블이 컴파일 될때 클래스에 추가된다. 그리고 가상함수 테이블 포인터가 각 개체에 추가된다. 그래서 이런경우 객체에 4바이트가 추가된다. 가상테이블을 통해서 오버라이딩으로 씹힌 함수에 접근하게 되며, 이런 경우를 동적 바인딩이라고 한다. 디폴트는 정적 바인딩이다.
기초 클래스의 소멸자의 경우 가상함수로 따로 만들지 않으면 소멸자가 호출되지 않으므로 꼭 가상함수로도 만들어야한다. 굳이 class1 내에서 부모의 소멸자를 호출하지 않아도 자동으로 호출됨에 주의하자.
class1* a = new class2; // class1 이 class2 를 상속받음
delete a; // 가상 함수가 없을 시 class1 의 소멸자가 호출됨
댓글 없음:
댓글 쓰기