연산자와 사본 생성자 간의 코드 복제 감소
-
16-09-2019 - |
문제
비 디폴트 카피 생성자 및 할당 연산자가 필요한 클래스가 있습니다 (포인터 목록이 포함되어 있음). 카피 생성자와 할당 연산자 간의 코드 복제를 줄이는 일반적인 방법이 있습니까?
해결책
모든 경우에 작동하는 사용자 정의 사본 생성자 및 할당 연산자를 작성하는 "일반적인 방법"은 없습니다. 그러나 "copy- & -swap"이라는 관용구가 있습니다.
class myclass
{
...
public:
myclass(myclass const&);
void swap(myclass & with);
myclass& operator=(myclass copy) {
this->swap(copy);
return *this;
}
...
};
많은 상황에서 유용합니다. 때때로 당신은 더 잘할 수 있습니다. 벡터 또는 문자열은 더 나은 할당을 가질 수 있으며, 충분히 큰 경우 스토리지를 할당 한 스토리지를 재사용 할 수 있습니다.
다른 팁
공통 코드를 개인 멤버 기능으로 고려하십시오. 간단한 (다소 고안된) 예 :
#include <iostream>
class Test
{
public:
Test(const char* n)
{
name = new char[20];
strcpy(name, n);
}
~Test()
{
delete[] name;
}
// Copy constructor
Test(const Test& t)
{
std::cout << "In copy constructor.\n";
MakeDeepCopy(t);
}
// Assignment operator
const Test& operator=(const Test& t)
{
std::cout << "In assignment operator.\n";
MakeDeepCopy(t);
}
const char* get_name() const { return name; }
private:
// Common function where the actual copying happens.
void MakeDeepCopy(const Test& t)
{
strcpy(name, t.name);
}
private:
char* name;
};
int
main()
{
Test t("vijay");
Test t2(t); // Calls copy constructor.
Test t3("");
t3 = t2; // Calls the assignment operator.
std::cout << t.get_name() << ", " << t2.get_name() << ", " << t3.get_name() << '\n';
return 0;
}
My &My::operator = (My temp) // thanks, sellibitze
{
swap (*this, temp);
return *this;
}
전문화 된 것을 구현하십시오 std::swap<> (My &, My &)
.
이미 꽤 많은 포스터에서 지적한 것처럼 연산자 = 복사 생성자가있는 새 개체를 생성 한 다음 Swap을 사용하는 것은 Operator =에서 코드를 복제 할 필요가없는 일반적인 기술입니다.
즉, 나는 그것이 적절한 지 여부를 결정하는 데 도움이되는이 기술의 프로와 사기를 지적하고 싶습니다.
프로 - 예외 안전
객체에 던지기를 유발할 수있는 자원 요구 사항이 있고 스왑이 던지지 않을 것이라고 가정하면이 기술은 예외 안전을 강력하게 보장합니다 (할당 된 객체가 다른 객체의 가치를 가져 왔거나 변경되지 않은 경우).
사기 - 자원 발자국
이 기술의 문제는 이전 제품이 출시되기 전에 완전한 새로운 개체를 만들어야한다는 것입니다. 객체에 많은 자원이 필요한 경우 문제가 될 수 있습니다.