프로그래밍/C++

복사 생성자

revivekirin 2024. 3. 20. 13:57

복사 생성자(copy constructor)는 객체의 복사본을 생성할 때 호출되는 생성자다. 기본적으로 디폴트로 컴파일러가 만들어 넣어주지만 

클래스 내부에서 메모리를 동적 할당 및 해제하고 이를 멤버 포인터 변수로 관리하고 있는 경우 복사 생성자를 적용하지 않으면 문제가 생길 수 있습니다.

#include <iostream>
	using namespace std;
	class CMyData
	{
	public:
	    CMyData() {cout<<"CMyData()"<<endl;}
	    
	    CMyData(const CMyData &rhs)
	    {
	      this->m_nData=rhs.m_nData;
	      cout<<"CMyData(const CMyData &)"<<endl;
	    }
	    
	    int GetData(void) const { return m_nData;}
	    void SetData(int nParam) { m_nData = nParam;}
	    
	private:
	    int m_nData = 0;
	};
    	int main()
	{
	  CMyData a;
	  a.SetData(10);
	  
      //복사 생성자가 호출되는 경우
	  CMyData b(a);
	  cout<<b.GetData()<<endl;
	  
	  return 0;
	}
main
a
0xFFF000BD0
object CMyData
b
0xFFF000BD4
object CMyData

 

 

4.1.1 함수 호출과 복사 생성자

TestFunc(CTestData param)의 문제점은 쓸데없이 CTestData 객체가 두 개라는 점이다.

param은 호출자의 a를 복사본으로 두고 복사본을 생성한다.

한 객체로 할 수 있는 일은 반드시 하나로 끝내야 한다.

해결책으로 참조자를 사용해 보자!

#include <iostream>
using namespace std;

class CTestData
{
public:
    CTestData(int nParam) : m_nData(nParam)
    {
	 cout << "CTestData(int)" << endl;
    }
	
    CTestData(const CTestData & rhs) : m_nData(rhs.m_nData)
	{
	 cout << "CTestData(const CTestData &rhs" << endl;
	}
	
	int GetData() const { return m_nData; }
	void SetData(int nParam) { m_nData = nParam; }
	
private:
	   int m_nData = 0;
};

//매개변수가 클래스에 대한 상수형 참조이다!
void TestFunc(const CTestData &param) // void TestFunc(CTestData param)
{
	cout << "TestFunc()" << endl;
	
	param.SetData(20);
}

int main()
{
	cout << "******Begin*******" << endl;
	CTestData a(10);
	TestFunc(a);
	
	cout << "a: " << a.GetData() << endl;
	cout << "******End******" << endl;
	return 0;
}

매개변수가 참조자가 되었을 때 call by reference인지 참조에 의한 호출인지 구별하기 어렵다는 점입니다. 위 코드에서 

TestFunc(CTestData *param) 일 경우 TestFunc(&a)로 적어할 것입니다.