类的设计者,应该像编程语言设计者考虑内置数据类型一样考虑类的设计,让这个类有自然地语法,直观的语义。你要考虑的内容如下:
1.新tpye的对象应该如何被创建和销毁?这需要考虑的是你的构造函数、析构函数的设计。如果类中包含指针,那么还得考虑如何应对指针带来的种种恐怖的问题:比如内存泄露,重复删除指针等等。
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吗?如果派生类只是简单的增加了基类的变量成员。说不定在基类中直接多定义几个成员会达到更好的效果。
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吗?如果派生类只是简单的增加了基类的变量成员。说不定在基类中直接多定义几个成员会达到更好的效果。