13.2 拷贝控制与资源管理
13.2.1 行为像值的类
行为像值的类拷贝时要先拷贝源对象的资源,再释放当前对象的资源,再指向新的资源
class Person {
private:
string *ptr;
int age;
public:
Person(const string &s = string()) : ptr(new string(s)), age(0) {}
Person(const Person &p) : ptr(new string(*p.ptr)), age(p.age) {}
Person& operator=(const Person& rhs) {
cout << "copy assignment" << endl;
auto newptr = new string(*rhs.ptr); // 拷贝资源
delete ptr; // 释放当前对象的资源
ptr = newptr; // 指针指向新的资源
age = rhs.age;
return *this;
}
~Person() { delete ptr; }
};
int main(int argc, char const *argv[]) {
Person p1("kavin");
Person p2;
p2 = p1;
return 0;
}
// copy assignment
13.2.2 行为像指针的类
行为像指针的类拷贝时两个对象的指针指向同一块资源,使用计数器统计资源的用户数量,当用户数量为0时释放资源,类似于shared_ptr
class Person
{
private:
string *ptr;
int age;
size_t *use;
public:
Person(const string &s = string()) : ptr(new string(s)), age(0), use(new size_t(1)) {}
Person(const Person &p) : ptr(p.ptr), age(p.age), use(p.use) { *use++; }
Person& operator=(const Person& rhs) {
++*rhs.use; // 先递增左侧对象的引用计数
if (--*use == 0) { // 再递减右侧对象的引用计数
delete ptr;
delete use;
}
ptr = rhs.ptr;
age = rhs.age;
use = rhs.use;
return *this;
}
~Person() {
if (--*use == 0) { // 引用计数为0就释放资源
delete ptr;
delete use;
}
}
void info() { cout << *use << endl; }
};
int main(int argc, char const *argv[])
{
Person p1("kavin");
Person p2;
p2 = p1;
p2.info();
return 0;
}
2