프로그램/C,C++
[C++ 기본 2] 11. 복사 생성자
naudhizb
2022. 3. 3. 00:09
반응형
// 11_복사생성자 92 page
#include <iostream>
class Point
{
int x, y;
public:
Point() : x(0), y(0) {} // 1
Point(int a, int b) : x(a), y(b) {} // 2
// 복사 생성자 : 자신과 동일 타입 객체를 인자로 받는 생성자
// 사용자가 만들지 않으면 컴파일러가 제공해 준다
Point(const Point& pt)
: x(pt.x), y(pt.y)
{
std::cout << "copy constructor" << std::endl;
}
};
int main()
{
Point p1; // 1번 생성자
Point p2(1, 1); // 2번 생성자
//Point p3(1); // Point(int) 모양의 생성자 필요.
// 없으므로 error
Point p4(p2); // Point(Point) 모양의 생성자가 필요
// 없지만 ok.
Point p5 = p2; // 복사 생성자. 직접이 아닌 복사 초기화
}
복사 생성자는 자신과 동일 타입을 인자로 받아 초기화를 수행한다.
// 11_복사생성자2
// 11_복사생성자 92 page
#include <iostream>
// 복사 생성자가 사용되는 경우 3가지 - 96 page
// 1. 객체 생성시 자신과 동일타입 객체로 초기화 할때
// 2. 함수가 인자를 call by value 로 전달 받을때
// => const 레퍼런스를 사용하자.!
// 3. 함수가 값 타입으로 객체를 반환 할때
// => 임시객체가 생성되면서 복사 생성자 호출.
class Point
{
int x, y;
public:
Point() : x(0), y(0) {}
Point(int a, int b) : x(a), y(b) {}
Point(const Point& pt) : x(pt.x), y(pt.y){ std::cout << "copy constructor" << std::endl; }
};
//void foo(Point pt) {} // Point pt = p1;
void foo(const Point& pt) {} // const Point& pt = p1;
int main()
{
Point p1(1, 2); // 2번 생성자
//Point p2(p1); // 복사 생성자
//Point p3 = p1; // 복사 생성자
foo(p1);
}
일반적으로 const 레퍼런스 타입을 받아 복사 생성자를 사용한다.
// 11_복사생성자2
// 11_복사생성자 92 page
#include <iostream>
// 복사 생성자가 사용되는 경우 3가지 - 96 page
// 1. 객체 생성시 자신과 동일타입 객체로 초기화 할때
// 2. 함수가 인자를 call by value 로 전달 받을때
// => const 레퍼런스를 사용하자.!
class Point
{
int x, y;
public:
Point() : x(0), y(0) { std::cout << "생성자1" << std::endl; }
Point(int a, int b) : x(a), y(b) { std::cout << "생성자2" << std::endl; }
Point(const Point& pt) : x(pt.x), y(pt.y) { std::cout << "copy constructor" << std::endl; }
~Point() { std::cout << "~Point()" << std::endl; }
};
Point foo() // return by value
{
Point pt(1,2);
return pt; // 이순간 리턴용 임시객체가 생성됩니다.
// 리턴용 임시객체를 pt를 복사해서 생성
}
int main()
{
Point ret;
std::cout << "----" << std::endl;
ret = foo();
std::cout << "----" << std::endl;
}
// 생성자1
// -----
// 생성자2
// 복사 생성자 - 리턴용 임시객체를 만들기 위해
// 소멸자 - pt 파괴
// 소멸자 - 리턴용 임시객체 파괴
//------
// 소멸자 - ret 파괴.
만약 함수가 클래스를 반환한다면, return by value이기 때문에 복사 생성자를 이용하여 복사된 클래스를 생성하고 리턴을 수행한다.
// 11_복사생성자2
#include <iostream>
class Point
{
public:
int x, y;
Point() : x(0), y(0) { std::cout << "생성자1" << std::endl; }
Point(int a, int b) : x(a), y(b) { std::cout << "생성자2" << std::endl; }
Point(const Point& pt) : x(pt.x), y(pt.y) { std::cout << "copy constructor" << std::endl; }
~Point() { std::cout << "~Point()" << std::endl; }
};
Point pt(1, 1); // 전역 객체
Point foo() // 값 반환 : 임시객체가 반환된다.
{
return pt;
}
Point& goo() // 참조 반환 : 임시객체를 만들지 말라는것
{ // 99page 마지막 소스
return pt;
}
int main()
{
foo().x = 10; // error. temporary 는 왼쪽에 올수없다
goo().x = 10; // ok
cout << "A" << "B" << "C";
}
// 정리
n = x;
x = 10;
// 1. primitive
int foo() { return x; } // x의 값.
int& goo() { return x; } // x 자체 (메모리)
// 2. user type
Point foo() { return pt; } // 임시객체
Point& goo() { return pt; } // pt의 자체(메모리)
만약 함수가 클래스 레퍼런스를 반환하는 경우에는 복사 생성자를 호출하지 않고 클래스 자체를 반환하게 된다.
반응형