条款19:设计class犹如设计type

本文探讨了对象初始化与赋值之间的区别,强调在设计class时需注意复制操作符和赋值操作符的使用。特别是对于自定义的智能指针,这种差异在工作中显得尤为重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类的设计者,应该像编程语言设计者考虑内置数据类型一样考虑类的设计,让这个类有自然地语法,直观的语义。你要考虑的内容如下:
1.新tpye的对象应该如何被创建和销毁?这需要考虑的是你的构造函数、析构函数的设计。如果类中包含指针,那么还得考虑如何应对指针带来的种种恐怖的问题:比如内存泄露,重复删除指针等等。

2.对象的初始化和对象的赋值该有什么差别。就是要考虑复制操作符和赋值操作符的区别。我们知道,有些工作只能在初始化中完成。而对于自己设计的智能指针,差别就更加明显了:

class Test;  
  
class U_PTR  
{  
    friend Test;  
    int use;  
    int* ptr;  
    U_PTR(int*p):ptr(p),use(1){};  
    ~U_PTR(){delete ptr;}  
};  
  
class Test  
{  
public:  
    Test(int*p):pValue(new U_PTR(p)){}  
    ~Test(){if(--pValue->use == 0) delete pValue;}  
    Test(const Test& rhs):pValue(rhs.pValue)  
    {  
        ++rhs.pValue->use;  
    }  
    Test& operator=(const Test& rhs)  
    {  
        ++rhs.pValue->use;  
        if(--pValue->use == 0)  
            delete pValue;  
        return *this;  
    }  
private:  
    U_PTR* pValue;  
};  

3.新的类型对象如果被pass by value,意味着什么?
4.什么是新type的合法值?这就要求你在构造函数、setter函数中进行错误检查工作。
5,你的新type需要配合某个继承图系吗?显然的,如果你的class是从别的基类继承下来的,那么你的会受到基类的束缚,尤其是基类中的虚函数。反之,如果你设计的是一个基类,那么记得把析构函数定义为虚函数,还用通过其他虚函数来设定一些接口。
6.你的type需要设么样的转化?尤其是构造函数是否声明为explict,决定了的是否会有隐式转化的发生。
7.什么样的操作符和函数对此新的type而言是合理的?
8.什么样的标准操作应该被驳回?你应该把它们声明为私有函数。
9.谁该取用新type的成员?就是说哪些函数时public,哪些是protected,哪些是private,哪些是friend。
10.什么是新type的“未声明接口”?
11.你的新type有多么一般化?是定义一个类模板呢,还是定义一个类模板。
12.你真的需要一个新type吗?如果派生类只是简单的增加了基类的变量成员。说不定在基类中直接多定义几个成员会达到更好的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值