您现在的位置是:主页 > news > 成品网站建设咨询/电销系统
成品网站建设咨询/电销系统
admin2025/4/27 1:37:41【news】
简介成品网站建设咨询,电销系统,网站编辑器是怎么做的,esp8266做网站例子1:导入简单的外覆类型 假如有一个用来表现日期的class设计构造函数: class Date{ public:Date(int month, int day, int year); }使用者很容易犯下两个错误:1.以错误的次序传递参数。2.传递一个无效的月份或天数。 为了预防这样的问题&…
例子1:导入简单的外覆类型
假如有一个用来表现日期的class设计构造函数:
class Date{
public:Date(int month, int day, int year);
}
使用者很容易犯下两个错误:1.以错误的次序传递参数。2.传递一个无效的月份或天数。
为了预防这样的问题,可以导入新的类型来获得预防,即导入外覆类型(wrapper types)来区别天数、月份和年份,然后于构造函数中使用这些类型:
struct Day{explicit Day(int d):val(d){}int val;
}
struct Month{
explicit Month(int m):val(m){}
int val;
}
struct Year{
explicit Year(int y):val(y){}
int val;
}class Date{
public:Date(const Month& m, const Day& d, const Year& y);
}Date d(30, 3, 2019); //错误,不正确的类型
Date d(Day(30), Month(12), Year(2019)); //错误,不正确的类型
Date d(Month(12), Day(30), Year(2019)); //ok,类型正确
例子2:限制类型
预防客户错误的另一个办法是,限制类型内什么事可做,什么事不能做。常见的限制是加上const
。例如条款3曾经说明为什么“以const
修饰operator
*的返回类型”可阻止客户因“用户自定义类型”而犯错。
避免无端与内置类型不兼容,真正的理由是为了提供行为一致的接口。很少有其他性质比得上“一-致性”更能导致“接口容易被正确使用”,也很少有其他性质比上“不一-致性”更加剧接口的恶化。STL容器的接口十分一致,这使它们非常容易被使用。
例子3:消除客户的资源管理责任
条款13导入了一个factory
函数,它返回一个指针指向Investment
继承体系内的一个动态分配对象:
Investment* createInvestment () ; //来自条款13;为求简化暂略参数。
为避免资源泄漏,createInvestment
返回的指针最终必须被删除,但那至少开启了两个客户错误机会:没有删除指针,或删除同一个指针超过一次。
条款13表明客户如何将createinvestment
的返回值存储于一个智能指针如auto_ptr
或tr1::shared_ptr
内,因而将delete
责任推给智能指针。
因此,较佳接口的设计原则是就令factory
函数返回-一个智能指针:
std::tr1::shared_ptr<Investment> createInvestment () ;
这便实质上强迫客户将返回值存储于一个tr1::shared_ptr
内,几乎消弭了忘记删除底部Investment
对象(当它不再被使用时)的可能性。
实际上,返回tr1::shared ptr
让接口设计者得以阻止一大群客户犯下资源泄漏的错误,因为就如条款14所言,tr1::shared ptr
允许当智能指针被建立起来时指定一个资源释放函数(所谓删除器,"deleter
")绑定于智能指针身上(auto_ptr
就没有这种能耐)。
假设class
设计者期许那些“从createInvestment
取得Investment*
指针”的客户将该指针传递给一个名为getRidOfInvestment
的函数,而不是直接使用delete。这样一个接口又开启通往另一个客户错误的大门,该错误是“企图使用错误的资源析构机制”(也就是拿delete
替换getRidOfInvestment
)。
createInvestment
的设计者可以返回一个“将getRidOfInvestment
绑定为删除器(deleter
)”的tr1::shared_ ptr
.
tr1::shared_ ptr
构造函数坚持其第一参数必须是个指针,而0不是指针,是个int
。是的,它可被转换为指针,但在此情况下并不够好,因为tr1::shared_ ptr
坚持要一个不折不扣的指针。转型(cast
)可以解决这个问题:
std::tr1::shared_ptr<Investment> //建立-一个null shared_ptr并以getRidofInvestment为删除器
pInv (static_cast<Investment*> (0) ,
getRidofInvestment); //条款27提到static_cast
因此,如果我们要实现 createInvestment
使它返回一-个tr1::shared_ ptr
并夹带getRidofInvestment
函数作为删除器,代码看起来像这样:
std::tr1::shared ptr<Investment> createInvestrment ()
{std::tr1::shared ptr<Investment> retval(static_cast<Investment*>(0), getRidOfInvestment) ;
retval = ... ; //令retval指向正确对象
return retval;
}
当然啦,如果被pInv
管理的原始指针(raw pointer
)可以在建立pInv
之前先确定下来,那么“将原始指针传给pInv
构造函数”会比“先将pInv
初始化为null
再对它做一次赋值操作”为佳。
tr1::shared_ ptr
有一个特别好的性质是:它会自动使用它的“每个指针专属的删除器”,因而消除另一个潜在的客户错误:所谓的“cross-DLL problem"。这个问题发生于“对象在动态连接程序库(DLL)中被new
创建,却在另一个 DLL内被 delete
销毁”。
总结:
1、好的接口容易被正确使用。应尽可能在你的所有接口中努力达成这性质。
2、“促进正确使用”的方法包括接口一致性,以及内置类型的行为兼容。
3、“防止误用”的方法包括建立新的类型、限制类型操作,束缚对象值等。
4、
tr1::shared_ptr
支持定制型删除器(custom deleter)。可防范DLL问题,可被用来自动解除互斥锁等。