전체 글 215

대입 연산자(=) 오버로딩으로 깊은 복사

대입 연산자를 이용한 깊은 복사 디폴트 대입연산자(=)의 문제점은 얕은 복사에 있다. 어떠한 객체를 삭제하면 같은 것을 가리키던 객체도 주소값을 잃어버린다. 이러한 문제점을 방지하기 위해 대입연산자 오버로딩을 이용하여 깊은 복사를 구현해보자. #include #include using namespace std; class Person { private: char* name; int age; public: Person(char* _name, int _age) :age(_age) { name = new char[strlen(_name)+1]; strcpy(name,_name); } Person& operator=(Person& ref) { // 대입연산자(=) 오버로딩 delete[] name; // 원본과..

카테고리 없음 2019.05.09

연산자 오버로딩

연산자 오버로딩 기존에 존재하던 연산자의 기본 기능 이외에 다른 기능을 추가시키는 것. 함수 오버로딩이 전달되는 인자에 따라 호출되는 함수가 달라지는것 처럼, 연산자 오버로딩은 피연산자의 종류에 따라서 연산의 방식이 달라진다. 예를 들면 +로는 int랑 int의 덧셈은 되지만 객체랑 객체의 덧셈은 할 수 없다. 그러나 연산자 오버로딩을 사용하면 객체간의 덧셈도 정의할 수 있게 된다. Point operator+(const Point& ref) { ... } 연산자 오버로딩은 'operator 키워드 + 연산자' 형태로 생성한다. operator 키워드와 연산자를 묶어서 함수의 이름을 정의하면, 일반 함수처럼 함수의 이름을 통한 함수 호출뿐만 아니라, 연산자를 이용한 함수의 호출도 허용해 준다. Point..

카테고리 없음 2019.05.09

friend (private 멤버 접근 허용)

friend - 다른 클래스나 외부 함수에 자신의 private 멤버 접근을 허용 * 선언은 클래스 내에 아무데나 해줘도 상관 없음 * 꼭 필요할 때 말고는 가급적 사용하지 않는 것을 추천 1. 다른 클래스를 friend로 선언하는 예 class Boy { private: int height; friend class Girl; // Girl 클래스를 friend로 선언 public: Boy(int len) : height(len) { } void ShowYourFriendInfo(Girl& frn); }; class Girl { private: char phNum[20]; friend class Boy; // Boy 클래스를 friend로 선언 public: Girl(char* num) { strcpy(..

카테고리 없음 2019.05.09

가상 소멸자 (연좌제 소멸)

C++ 컴파일러는 포인터의 자료형을 기준으로 판단하기 때문에, 소멸자 호출 시 해당 자료형 클래스의 소멸자만 호출된다. 예를 들어, Parent* parent = new Child(); 로 선언한 객체를 소멸하면 Parent의 소멸자만 호출되고, Child의 나머지 부분은 메모리에 계속 남게 된다. 상속 관계를 갖는 객체 소멸 과정에서는 자료형에 상관없이 모든 소멸자가 호출되어야 한다. 가상 소멸자 상속 계층의 맨 위에 존재하는 부모 클래스의 소멸자를 virtual로 정의하면 이를 상속하는 자식 클래스의 소멸자들도 모두 '가상 소멸자'로 선언된다. 가상 소멸자가 호출되면, 상속의 계층 구조상 맨 아래에 존재하는 자식 클래스의 소멸자가 대신 호출되면서 부모 클래스의 소멸자까지 순차적으로 호출된다. virt..

카테고리 없음 2019.05.09

가상 함수, 추상 클래스

C++ 컴파일러는 포인터의 자료형을 기준으로 판단한다. Parent 클래스의 자식 클래스인 Child 객체를 생성했으나, 여전히 Parent 객체로 인식한다. void main() { Parent* parent = new Child(); parent->ChildFunc(); // 에러 Child* child = parent; // 에러 } * Java에서는 이런 상황에서 자식 클래스(Child)의 함수가 우선적으로 호출된다. 가상 함수 (Virtual Function) 가상함수는 포인터 변수가 실제로 가리키는 객체를 참조하여 호출 대상을 결정한다. class Child : public Parent { public: virtual void ChildFunc() {...} } void main() { Par..

카테고리 없음 2019.05.09

생성자 이니셜라이저

생성자에서 멤버를 초기화 할 때, 둘 중 어느 방법이 성능 향상에 도움을 줄까? 1. 이니셜라이저로 초기화 Boy(int _age) : age(_age) { } 2. 생성자 몸체에서 = (대입연산자)로 초기화 Boy(int _age) { age = _age; } 결론부터 말하면 이니셜라이저로 초기화하는게 성능에 더 좋다. 이니셜라이저를 이용하면 선언과 동시에 초기화가 이루어지는 형태로 바이너리 코드가 생성된다. 반면, 생성자 몸체에서 대입연산(=)을 통해 초기화를 하면, 선언과 초기화가 따로따로 이루어지는 형태로 바이너리 코드가 생성된다.

카테고리 없음 2019.05.09

상속

상속 관계의 의미 1) IS-A 관계 - 대부분 이 의미로 쓰인다. - ex) 태블릿 PC는 노트북이다, 노트북은 컴퓨터이다. / 사람은 동물이다, 동물은 생물이다. 2) HAS-A 관계 - 이렇게는 잘 쓰이지 않고 복합 관계로 대신한다 - ex) 경찰관은 총을 소지한다. 상속 #include using namespace std; class MyFriendInfo { private: char* name; int age; public: MyFriendInfo(char* _name, int _age) : age(_age) { name = new char[strlen(_name)+1]; strcpy(name,_name); age = _age; } ~MyFriendInfo(){ cout

카테고리 없음 2019.05.09