您现在的位置是:主页 > news > 成品网站建设咨询/电销系统

成品网站建设咨询/电销系统

admin2025/4/27 1:37:41news

简介成品网站建设咨询,电销系统,网站编辑器是怎么做的,esp8266做网站例子1:导入简单的外覆类型 假如有一个用来表现日期的class设计构造函数: class Date{ public:Date(int month, int day, int year); }使用者很容易犯下两个错误:1.以错误的次序传递参数。2.传递一个无效的月份或天数。 为了预防这样的问题&…

成品网站建设咨询,电销系统,网站编辑器是怎么做的,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_ptrtr1::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问题,可被用来自动解除互斥锁等。