할당 연산자와 복사 생성자의 차이점은 무엇입니까?


105

C ++에서 할당 생성자와 복사 생성자의 차이점을 이해하지 못합니다. 다음과 같습니다.

class A {
public:
    A() {
        cout << "A::A()" << endl;
    }
};

// The copy constructor
A a = b;

// The assignment constructor
A c;
c = a;

// Is it right?

할당 생성자 및 복사 생성자의 메모리를 할당하는 방법을 알고 싶습니다.


2
당신이 있습니까 좋은의 C ++를 책을 ?
sbi

답변:


160

복사 생성자는 초기화하는 데 사용됩니다 이전에 초기화되지 않은 다른 개체의 데이터에서 개체를.

A(const A& rhs) : data_(rhs.data_) {}

예를 들면 :

A aa;
A a = aa;  //copy constructor

할당 연산자는 a의 데이터를 교환하는 데 사용됩니다 이전에 초기화 다른 개체의 데이터와 객체를.

A& operator=(const A& rhs) {data_ = rhs.data_; return *this;}

예를 들면 :

A aa;
A a;
a = aa;  // assignment operator

복사 구성을 기본 구성과 할당으로 바꿀 수 있지만 효율성이 떨어집니다.

(부수적으로 : 위의 구현은 컴파일러가 무료로 제공하는 것과 정확히 일치하므로 수동으로 구현하는 것은별로 의미가 없습니다.이 두 가지 중 하나가 있으면 일부 리소스를 수동으로 관리 할 가능성이 큽니다. 이 경우 The Rule of Three 에 따라 다른 하나와 소멸자가 필요할 가능성이 큽니다.)


4
그냥 참고 : 현재 (C ++ 11 이후), 그들은 명시 적으로 디폴트 할 수 있습니다 =default;.
Deduplicator

2
@Deduplicator 그것은 당신이, 사소한 생성자를 필요로 분류 준수 할 때, 그 언급하는 것도 중요 합니다 = default 그들을 기본 ctor에 필요한 곳에 : 단순히 Standardese 수준 (따라서 자신 여전히 사용자 정의의 ctor로 계산에 의해 빈 몸을 구현 )는 사소하지 않으며 사소한 행위자가 필요한 분류에서 유형을 실격시킵니다.
underscore_d

@sbi 복사 생성자를 사용하지 않고 대신 할당 연산자를 사용하는 경우 인수를 사용하거나 사용하지 않고 생성자를 호출하여 객체를 먼저 생성 한 다음 할당 연산자를 사용하고 RHS를 기반으로 새 값을 할당한다고 말할 수 있습니까? 복사 생성자를 사용하는 경우에도 동일한 생성자가 호출되지만 초기화에 사용되는 값은 다른 객체에서 가져온 것입니다.
Rajesh

@Rajesh : 나는 당신이 묻는 것에 대해 혼란스럽고, 내 느낌은 당신도 혼란 스럽기 때문입니다. :)당신이 말하는 것을 다시 설명해 주시겠습니까?
sbi

1
@ CătălinaSîrbu : 할 수 있습니다. 두 개의 독립적 인 기능입니다.
sbi

41

복사 생성자와 할당 연산자의 차이는 초보 프로그래머에게 많은 혼란을 야기하지만 실제로 그렇게 어렵지는 않습니다. 요약 :

  • 복사하기 전에 새 객체를 만들어야하는 경우 복사 생성자가 사용됩니다.
  • 복사하기 전에 새 개체를 만들 필요가없는 경우 할당 연산자가 사용됩니다.

할당 연산자의 예 :

Base obj1(5); //calls Base class constructor
Base obj2; //calls Base class default constructor
obj2 = obj1; //calls assignment operator

복사 생성자의 예 :

Base obj1(5);
Base obj2 = obj1; //calls copy constructor

할당 연산자가 이전 객체의 파괴와 새로운 객체의 생성을 효과적으로 결합한다고 말하는 것이 공평할까요?하지만 (1) 이전 객체의 파괴 단계 중 하나가 새로운 구성 단계 중 하나, 두 단계 모두 생략 할 수 있습니다. (2) 할당 연산자는 객체가 자신에게 할당 된 경우 나쁜 일을해서는 안됩니다.
supercat

vector <A> v3그런 다음 v3 = v2 ( v2이전에 선언되고 요소를 포함하는 vector<A>) 내 명시 적 A복사 생성자를 대신 호출 operator=합니까? 대신에 호출 될 것으로 예상 operator=했습니다. copy constructorv3개체가 내가 할당을 수행 한 시점에 이미 선언 되었기 때문에
Cătălina Sîrbu

19

첫 번째는 복사 초기화이고 두 번째는 할당입니다. 할당 생성자와 같은 것은 없습니다.

A aa=bb;

컴파일러 생성 복사 생성자를 사용합니다.

A cc;
cc=aa;

기본 생성자를 사용하여을 생성 cc한 다음 operator =이미 존재하는 객체에 대한 * 할당 연산자 ** ( )를 사용합니다.

할당 생성자 및 복사 생성자의 메모리를 할당하는 방법을 알고 싶습니다.

이 경우 메모리 할당이 의미하는 바를 IDK하지만 어떤 일이 발생하는지 확인하려면 다음을 수행 할 수 있습니다.

class A
{
public :
    A(){ cout<<"default constructor"<<endl;};
    A(const A& other){ cout<<"copy constructor"<<endl;};
    A& operator = (const A& other){cout <<"assignment operator"<<endl;}
};

또한 다음을 살펴 보시기 바랍니다.

변환 생성자 대신 복사 생성자가 호출되는 이유는 무엇입니까?

3의 법칙은 무엇입니까?


5

간단히 말해서

복사 생성자는 기존 개체의 복사본으로 기존 개체에서 새 개체를 만들 때 호출됩니다. 그리고 할당 연산자는 이미 초기화 된 개체에 다른 기존 개체의 새 값이 할당 될 때 호출됩니다.

예-

t2 = t1;  // calls assignment operator, same as "t2.operator=(t1);"
Test t3 = t1;  // calls copy constructor, same as "Test t3(t1);"

4

@Luchian Grigore Said가 이렇게 구현 된 것

class A
{
public :
    int a;
    A(){ cout<<"default constructor"<<endl;};
    A(const A& other){ cout<<"copy constructor"<<endl;};
    A& operator = (const A& other){cout <<"assignment operator"<<endl;}
};

void main()
{
    A sampleObj; //Calls default constructor
    sampleObj.a = 10;

    A copyConsObj  = sampleObj; //Initializing calls copy constructor

    A assignOpObj; //Calls default constrcutor
    assignOpObj = sampleObj; //Object Created before so it calls assignment operator
}

산출


기본 생성자


복사 생성자


기본 생성자


할당 연산자



4

복사 생성자와 할당 생성자의 차이점은 다음과 같습니다.

  1. 복사 생성자의 경우 새 개체를 만듭니다.<classname> <o1>=<o2> )
  2. 할당 생성자의 경우 객체를 생성하지 않는다는 것은 이미 생성 된 객체 ( <o1>=<o2>) 에 적용됨을 의미합니다 .

그리고 둘 다의 기본 기능은 동일하며 데이터를 o2에서 o1 멤버별로 복사합니다.


2

이 주제에 대해 한 가지 더 추가하고 싶습니다. "할당 연산자의 연산자 함수는 클래스의 멤버 함수로만 작성되어야합니다." 다른 이항 또는 단항 연산자와는 달리 친구 함수로 만들 수 없습니다.


1

복사 생성자에 대해 추가 할 사항 :

  • 값으로 객체를 전달할 때 복사 생성자를 사용합니다.

  • 객체가 값으로 함수에서 반환되면 복사 생성자를 사용합니다.

  • 다른 객체의 값을 사용하여 객체를 초기화 할 때 (예시처럼).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.