728x90
C++
복사 생성자
- 복사 생성자는 호출되는 시점이 다른 일반 생서어자와 차이가 있기 때문에 이름이 붙었다.
- 멤버 대 멤버의 복사에 사용되는 원본을 변경시키는 것은 복사의 개념을 무너뜨리는 행위가 되니, 키워드 const를 삽입해서 이러한 실수를 막아 놓는 것이 좋다.
- 복사 생성자를 정의하지 않으면, 멤버 대 멤버의 복사를 진행하는 디폴트 복사 생성자가 자동으로 삽입된다.
- 디폴트 복사 생성자를 막기 위해서는 복사 생성자의 묵시적 호출을 허용하지 않으면 된다. 이러한 목적으로 explicit이 사용된다. explicit을 사용하면 묵시적 변환이 발생하지 않아서 대입 연산자를 이용한 객체의 생성 및 초기화가 불가능해진다.
- 전달인자가 하나인 생성자가 있다면, 이 역시 묵시적 변환이 발생한다.
- 복사 생성자의 매개변수는 참조형이여야 한다.
깊은 복사와 얕은 복사
- 디폴트 복사 생성자는 멤버 대 멤버의 복사를 진행한다. 그리고 이러한 방식의 복사를 가리켜 얕은 복사(shallow copy)라고 한다. 이는 멤버변수가 힙의 메모리 공간을 참조하는 경우에 문제가 된다.
- 디폴트 복사 생성자는 멤버 대 멤버의 단순 복사를 진행하기 때문에 복사의 결과로 하나의 문자열을 두 개의 객체가 동시에 참조하는 꼴을 만들 수있다. 그리고 이로 인해서 객체의 소멸과정에서 문제가 발생한다. 이미 지워진 문자열을 대상으로 delete 연산을 하기 때문에 문제가 된다. 따라서 복사 생성자를 정의할 때에는 이러한 문제가 발생하지 않도록 신경을 써야한다.
- 깊은 복사(deep copy)는 멤버뿐만 아니라, 포인터를 참조하는 대상까지 깊게 복사한다는 뜻이다. 객체 별로 각각 문자열을 참조하기 때문에, 위에서 언급한 객체 소멸과정에서의 문제는 발생하지 않는다.
복사 생성자의 호출 시점
- 기존에 생성된 객체를 이용해서 새로운 객체를 초기화하는 경우
- call by value 방식의 함수호출 과정에서 객체를 인자로 전달하는 경우
- 객체를 반환하되, 참조형으로 반환하지 않는 경우
- 이들은 객체를 새로 생성하고, 생성과 동시에 동일한 자료형의 객체로 초기화한다는 공통점을 가지고 있다.
- 함수가 값을 반환하면, 별도의 메모리 공간이 할당되고, 이 공간에 반환 값이 저장된다.(반환 값으로 초기화된다)\
- 객체를 반환하게 되면, 임시객체라는 것이 생성되고, 이 객체의 복사 생성자가 호출되면서 return문에 명시된 객체가 인자로 전달된다.
- 클래스 외부에서 객체의 멤버를 호출하기 위해 필요한 것은 다음 세 가지 중 하나이다.
- 객체에 붙여진 이름
- 객체의 참조 값(객체 참조에 사용되는 정보
- 객체의 주소 값
- 임시객체는 다음 행으로 넘어가면 바로 소멸된다.
- 참조자에 참조되는 임시객체는 바로 소멸되지 않는다.
const/friend
const 객체와 특성
- 객체에 const 선언이 붙게 되면, 이 객체를 대상으로는 const 멤버함수만 호출이 가능하다. 이는 객체의 const 선언은 이 객체의 데이터 변경을 허용하지 않겠다 라는 의미를 가진다. 때문에 const 멤버함수의 호출만 허용하는 것이다.
- 멤버변수에 저장된 값을 수정하지 않는 함수는 가급적 const로 선언해서, const 객체에서도 호출이 가능하도록 할 필요가 있다.
const 함수 오버로딩
- 함수의 오버로딩이 성립하려면 매개변수의 수나 자료형이 달라야 한다. 하지만 const의 선언유무로 함수 오버로딩의 조건에 해당이된다.
friend
- A 클래스가 B 클래스를 대상으로 friend 선언을 하면, B 클래스는 A 클래스의 private 멤버에 직접 접근이 가능하다.
- 단, A 클래스도 B 클래스의 private 멤버에 직접 접근이 가능 하려면, B 클래스가 A 클래스를 대상으로 friend 선언을 해줘야 한다. 이렇듯 friend 선언은 private 멤버의 접근을 허용하는 선언이다.
- friend 선언은 객체지향의 대명사 중 하나인 정보은닉을 무너뜨리는 문법이기 때문에 소극적으로 사용해야 한다.
- 전역함수를 대상으로도, 클래스의 멤버함수를 대상으로도 friend 선언이 가능하다.
static
- 전역변수에 선언된 static
- 선언된 파일 내에서만 참조를 허용하겠다는 의미이다.
- 함수 내에 선언된 static
- 한번만 초기화되고, 지역변수와 달리 함수를 빠져나가도 소멸되지 않는다.
- static 멤버변수(클래스 변수)
- static 멤버변수는 클래스 변수라고도 한다. 일반적인 멤버변수와 달리 클래스당 하나씩만 생성되기 때문이다.
- static 멤버변수는 어디서든 접근이 가능한 변수이다. priavete로 선언되면 해당 클래스의 객체들만 접근이 가능하지만, public으로 선언되면, 클래스의 이름 또는 객체의 이름을 통해서 어디서든 접근이 가능하다.
- static 멤버함수
- static 멤버함수 역시 그 특성이 static 멤버변수와 동일하다.
- 선언된 클래스의 모든 객체가 공유한다.
- public으로 선언이 되면, 클래스의 이름을 이용해서 호출이 가능하다.
- 객체의 멤버로 존재하는 것이 아니다.
- static 멤버함수 내에서는 static 멤버변수와 static 멤버함수만 호출이 가능하다.
- static 멤버함수 역시 그 특성이 static 멤버변수와 동일하다.
mutable
- const 함수 내에서의 값의 변경을 예외적으로 허용한다.
상속
- 기존에 정의해 놓은 클래스의 재활용을 목적으로 만들어진 문법적 요소가 상속이다.
- 기능의 처리를 실제로 담당하는 클래스를 가리켜 컨트롤(control) 클래스 또는 핸들러(handler) 클래스라 한다.
- 상속을 하게 되면, 상속의 대상이 되는 클래스의 멤버까지도 객체 내에 포함이 된다.
- 유도 클래스의 객체생성 과정에서 기초 클래스의 생성자는 100% 호출된다.
- 유도 클래스의 생성자에서 기초 클래스의 생성자 호출을 명시하지 않으면, 기초 클래스의 void 생성자가 생성된다.
- 유도 클래스의 객체가 소멸될 때에는, 유도 클래스의 소멸자가 실행되고 난 다음에 기초 클래스의 소멸자가 실행된다. 스택에 생성된 객체의 소멸순서는 생성순서와 반대이다. 생성자에서 동적 할당한 메모리 공간은 소멸자에서 해제한다.
세가지 형태의 상속
- public Base
- private를 제외한 나머지는 그냥 그대로 상속한다.
- protected Base
- protected 보다 접근의 범위가 넓은 멤버는 protected로 변경시켜서 상속하겠다.
- private Base
- private보다 접근의 범위가 넓은 멤버는 private으로 변경시켜서 상속하겠다.
- private 상속이 이뤄진 클래스를 다시 상속할 경우, 멤버함수를 포함하여 모든 멤버가 접근불가가 되기 때문에 사실상 의미 없는 상속이 되고 만다.
상속을 위한 조건
- IS-A 관계의 성립
- 기초 클래스와 유도 클래스간에 IS-A 관계가 성립해야 한다.
- Has-A 관계도 상속의 조건은 되지만 복합 관계로 이를 대신하는 것이 일반적이다.
728x90
'Study > TIL(Today I Learned)' 카테고리의 다른 글
24.12.07 CS (1) | 2024.12.07 |
---|---|
24.12.05 CS (0) | 2024.12.06 |
24.11.28 면접 후기 (1) | 2024.11.28 |
24.11.27 서버, AWS (0) | 2024.11.27 |
24.11.26 C++, 책 (0) | 2024.11.26 |