当前位置: 首页 > news >正文

西安seo网站公司wordpress 卡盟模板

西安seo网站公司,wordpress 卡盟模板,响应式网站切图,小程序登录不了文章目录基本概念直接调用一个重载的运算符函数某些运算符不应该被重载使用与内置类型一致的含义选择作为成员或者非成员输入和输出运算符重载输出运算符输出运算符尽量减少格式化操作输入输出运算符必须是非成员函数重载输入运算符算术和关系运算符相等运算符… 文章目录基本概念直接调用一个重载的运算符函数某些运算符不应该被重载使用与内置类型一致的含义选择作为成员或者非成员输入和输出运算符重载输出运算符输出运算符尽量减少格式化操作输入输出运算符必须是非成员函数重载输入运算符算术和关系运算符相等运算符关系运算符赋值运算符复合赋值运算符下标运算符递增和递减运算符区分前置和后置运算符显式地调用后置运算符成员访问运算符函数调用运算符含有状态的函数对象类lambda是函数对象表示lambda及相应捕获行为的类标准库定义的函数对象在算法中使用标准库函数对象transform函数可调用对象与function不同类型可能具有相同的调用形式重载的函数与function重载、类型转换与运算符类型转换运算符定义含有类型转换运算符的类显式的类型转换运算符避免有二义性的类型转换基本概念 如果一个运算符函数是成员函数则它的第一个左侧运算对象绑定到隐式的this指针上因此成员运算符函数的显式参数数量比运算符的运算对象总数少一个。 对于一个运算符函数来说它或者是类的成员或者至少含有一个类类型的参数 错误不能为int重定义内置的运算符 int operator(int,int);我们可以重载大多数运算符但不是全部。我们只能重载已有的运算符而无权发明新的运算符号。 对于一个重载的运算符来说其优先级和结合律与对应的内置运算符保持一致。 直接调用一个重载的运算符函数 一个非成员运算符函数的等价调用 data1data2; //普通的表达式 operator(data1,data2); // 等价的函数调用调用成员运算符函数 data1data2; //基于“调用”的表达式 data1.operator(data2); // 对成员运算符函数的等价调用某些运算符不应该被重载 通常情况下不应该重载逗号、取地址、逻辑与、逻辑或等运算符。 使用与内置类型一致的含义 选择作为成员或者非成员 当我们定义重载的运算符时必须首先决定是将其声明为类的成员函数还是声明为一个普通的非成员函数。在某些时候我们别无选择因为有的运算符必须作为成员另一些情况下运算符作为普通函数比作为成员更好。 %通常定义为非成员 %通常定义为类成员因为它会改变对象的状态 通常定义为类成员因为它会改变对象的状态 -必须定义为类成员否则编译会报错 通常定义为非成员 通常定义为非成员 通常定义为非成员 ()必须定义为类成员否则编译会报错 输入和输出运算符 IO标准库分别使用和执行输入和输出操作。对于这两个运算符来说IO库定义了用其读写内置类型的版本而类则需要自定义适合其对象的新版本以支持IO操作。 重载输出运算符 通常情况下输出运算符的第一个形参是一个非常量ostream对象的引用。之所以ostream是非常量是因为向流写入内容会改变其状态而该形参是引用是因为我们无法直接复制一个ostream对象。 第二个形参一般来说是一个常量的引用该常量是我们想要打印的类类型。第二个形参是引用的原因是我们希望避免复制实参而之所以该形参可以是常量是因为通常情况下打印对象不会改变对象的内容。 为了与其他输出运算符保持一致operator一般要返回它的ostream形参。 示例代码 ostream operator(ostreamos,const Sales_data item){//输出内容ositem.isbn() item.units_sold;//返回ostreamreturn os; }输出运算符尽量减少格式化操作 用于内置类型的输出运算符不太考虑格式化操作尤其不会打印换行符用户希望类的输出运算符也像如此行事。如果运算符打印了换行符则用户就无法在对象的同一行内接着打印一些描述性的文本了。相反令输出运算符尽量减少格式化操作可以使用户有权控制输出的细节。 输入输出运算符必须是非成员函数 与iostream标准库兼容的输入输出运算符必须是普通的非成员函数而不能是类的成员函数。否则它们的左侧运算对象将是我们的类的一个对象 Sales_data data; datacout; //如果operator是Sales_data的成员因此如果我们希望为类自定义IO运算符则必须将其定义为非成员函数。IO运算符通常需要读写类的非公有数据成员所以IO运算符一般被声明为友元。 重载输入运算符 通常情况下输入运算符的第一个形参是运算符将要读取的流的引用第二个形参是将要读入到的非常量对象的引用。该运算符通常会返回某个给定流的引用。 第二个形参之所以必须是个非常量是因为输入运算符本身的目的就是将数据读入到这个对象中。 输入运算符必须处理输入可能失败的情况而输出运算符不需要。 输入时的错误 当流含有错误类型的数据时读取操作可能失败。当读取操作到达文件末尾或者遇到输入流的其他错误时也会失败。 通常情况下输入运算符只设置failbit。除此之外设置eofbit表示文件耗尽而设置badbit表示流被破坏。 算术和关系运算符 通常我们把算术和关系运算符定义成非成员函数以允许对左侧或右侧的运算对象进行转换。因为这些运算符一般不需要改变运算对象的状态所以形参都是常量的引用。 算术运算符通常会计算它的两个运算对象并得到一个新值这个值有别于任意一个运算对象常常位于一个局部变量之内操作完成后返回该局部变量的副本作为其结果。如果类定义了算术运算符则它一般也会定义一个对应的复合赋值运算符。此时最有效的方式是使用复合赋值来定义算术运算符 Sales_data operator(const Sales_data lhs,const Sales_data rhs){Sales_data sum lhs;//把lhs的数据成员拷贝给sumsumrhs; //使用复合赋值运算符将rhs加到sum中return sum; }如果类同时定义了算术运算符和相关的复合赋值运算符则通常情况下应该使用复合赋值来实现算术运算符。 相等运算符 通常情况下c中的类通过定义相等运算符来检验两个对象是否相等。也就是说它们会比较对象的每一个数据成员只有当所有对应的成员都相等时才认为两个对象相等。 关系运算符 定义了相等运算符的类也常常但不总是包括关系运算符。特别是因为关联容器和一些算法要用到小于运算符所以定义operator会比较有用。 通常情况下关系运算符应该 定义顺序关系令其与关联容器中对关键字的要求一致。如果类同时也含有 运算符的话则定义一种关系令其与 保持一致。特别是如果两个对象是 ! 的那么一个对象应该 另外一个。 如果存在唯一一种逻辑可靠的 定义则应该考虑为这个类定义 运算符。如果类同时还包含 则当且仅当 的定义和 产生的结果一致时才定义 运算符。 赋值运算符 我们可以重载赋值运算符不论形参的类型是什么赋值运算符都必须定义为成员函数。 示例代码 复合赋值运算符 复合赋值运算符不非得是类的成员不过我们还是倾向于把包括复合赋值在内的所有赋值运算都定义在类的内部。为了与内置类型的复合赋值保持一致类中的复合赋值运算符也要返回其左侧运算对象的引用。 示例代码 赋值运算符必须定义成类的成员复合赋值运算符通常情况下也应该这样做。这两类运算符都应该返回左侧运算对象的引用。 下标运算符 表示容器的类通常可以通过元素在容器中的位置访问元素这些类一般会定义下标运算符operator[ ]。 下标运算符必须是成员函数。 为了与下标的原始定义兼容下标运算符通常以所访问元素的引用作为返回值这样做的好处是下标可以出现在赋值运算符的任意一端。进一步我们最好同时定义下标运算符的常量版本和非常量版本当作用于一个常量对象时下标运算符返回常量引用以确保我们不会给返回的对象赋值。 示例代码 递增和递减运算符 定义递增和递减运算符的类应该同时定义前置版本和后置版本。这些运算符通常应该被定义成类的成员。 为了与内置版本保持一致前置运算符应该返回递增或递减后对象的引用。 区分前置和后置运算符 前置和后置版本使用的是同一个符号意味着其重载版本所用的名字将是相同的并且运算对象的数量和类型也相同。为了解决这个问题后置版本接受一个额外的不被使用的int类型的形参。当我们使用后置运算符时编译器为这个形参提供一个值为0的实参。尽管从语法上来说后置函数可以使用这个额外的形参但是在实际过程中通常不会这么做。这个形参的唯一作用就是区分前置版本和后置版本的函数而不是真的要在实现后置版本时参与运算。 为了与内置版本保持一致后置运算符应该返回对象的原值递增或递减之前的值返回的形式是一个值而非引用。 后置版本示例代码 显式地调用后置运算符 StrBlobPtr p(a1); p.operator(0); //调用后置版本的operator p.operator(); //调用前置版本的operator成员访问运算符 箭头运算符 - 必须是类的成员。解引用运算符 * 通常也是类的成员。 重载的箭头运算符必须返回类的指针或者自定义了箭头运算符的某个类的对象。 函数调用运算符 如果类重载了函数调用运算符则我们可以像使用函数一样使用该类的对象。因为这样的类同时也能存储状态所以与普通函数相比它们更加灵活。 函数调用运算符必须是成员函数一个类可以定义多个不同版本的调用运算符相互之间应该在参数数量或类型上有所区别。 如果类定义了调用运算符则该类的对象称作函数对象。因为可以调用这种对象所以我们说这些对象的“行为像函数一样”。 class absInt{int operator()(int val)const{return val 0 ? -val : val;} }int i-42; absInt absObj; //含有函数调用运算符的对象 int ui absObj(i); //将i传递给absObj.operator()即使absObj只是一个对象而非函数我们也能“调用”该对象。调用对象实际上是在运行重载的调用运算符。该例中该运算符接受一个int值并返回其绝对值。 含有状态的函数对象类 和其他类一样函数对象类除了operator()之外也可以包含其他成员。函数对象类通常含有一些数据成员这些成员被用于定制调用运算符中的操作。 示例代码 #ifndef PRINTSTRING_H #define PRINTSTRING_H#includeiostream #includestring using namespace std;class PrintString { public:PrintString(ostream ocout,char c ) :os(o),sep(c){}void operator()(const string s)const { os s sep; } private:ostream os;char sep; }; #endif 测试代码 void testPrintString() {PrintString p1;p1(hello);PrintString p2(cout, !);p2(hello); }输出结果 hello hello!示例代码 //IntCompare类 class IntCompare { public:IntCompare(int v) :val(v) {}bool operator()(int v) { return val v; } private:int val; };//测试代码vectorintvec { 1,2,3,2,1 };int oldVal 2;int newVal 200;IntCompare icmp(oldVal);replace_if(vec.begin(),vec.end(),icmp,newVal);for (auto a:vec) {cout a ;}输出结果 1 200 3 200 1lambda是函数对象 在lambda表达式产生的类中含有一个重载的函数调用运算符例如 [](const string a , const string b){return a.size()b.size();}其行为类似于下面这个类的一个未命名对象 class ShortString{ public:bool operator()(const string a , const string b) {return a.size()b.size();} }该类可被如下调用 stable_sort(words.begin(),words.end(),ShortString());当stable_sort内部的代码每次比较两个string时就会“调用”这一对象此时该对象将调用运算符的函数体判断第一个string的大小小于第二个时返回true。 表示lambda及相应捕获行为的类 当一个lambda表达式通过引用捕获变量时将由程序负责确保lambda执行时引用所引的对象确实存在。因此编译器可以直接使用该引用而无须在lambda产生的类中将其存储为数据成员。 如果通过值捕获的变量被拷贝到lambda中这种lambda产生的类必须为每个值捕获的变量建立对应的数据成员同时创建构造函数令其使用捕获的变量的值来初始化数据成员。 示例如下 [sz](const string a){return a.size()sz;}该lambda表达式产生的类将形如 class SizeComp{ public:SizeComp(size_t n):sz(n){} //该形参对应捕获的变量//该调用运算符的返回类型、形参和函数体都与lambda一致bool operator(){const string s}const{return s.size()sz;} private:size_t sz;//该数据成员对应通过值捕获的变量 }这个类含有一个数据成员以及一个用于初始化该成员的构造函数。这个合成的类不含有默认构造函数因此要想使用这个类必须提供一个实参 auto wc find_if(words.begin(),words.end(),SizeComp(sz));lambda表达式产生的类不含默认构造函数、赋值运算符及默认析构函数它是否含有默认的拷贝 / 移动构造函数则通常要视捕获的数据成员类型而定。 标准库定义的函数对象 标准库定义了一组表示算术运算符、关系运算符和逻辑运算符的类每个类分别定义了一个执行命名操作的调用运算符。例如plus类定义了一个函数调用运算符用于对一对运算对象执行的操作modulus类定义了一个调用运算符执行二元的%操作equal_to类执行。 示例代码 plusintintAdd;negateintintNegate;//negateint可对int取反int sum intAdd(10,20);cout sum endl;sum intNegate(intAdd(10, 20));cout sum endl;sum intAdd(10, intNegate(20));cout sum endl;输出结果 30 -30 -10标准库函数对象下表所列的类型定义在functional头文件中 在算法中使用标准库函数对象 表示运算符的函数对象常用来替换算法中的默认运算符。例如默认情况下排序算法使用operator将序列按照升序排列如果要执行降序排列的话我们可以传入一个greater类型的对象。该类将产生一个调用运算符并负责执行待排序类型的大于运算。例如如果svec是一个vectorstring sort(svec.begin(),svec.end(),greaterstring());示例代码 vectorintvec{ 1,3,5,7,9,2,4,6,8,10 };//统计大于4的值有多少个int num count_if(vec.begin(),vec.end(),bind2nd(greaterint(),4));cout num endl;vectorstringsv{hello,hello,hi,nihao,nihao};//找到第一个不等于hello的字符串auto its find_if(sv.begin(),sv.end(), bind2nd(not_equal_tostring(), hello));cout *its endl;//将所有的值乘以2transform(vec.begin(), vec.end(), vec.begin(), bind2nd(multipliesint(), 2));for (auto a:vec) {cout a ;}cout endl;输出结果 6 hi 2 6 10 14 18 4 8 12 16 20transform函数 transform函数的作用是将某操作应用于指定范围的每个元素。transform函数有两个重载版本 transform(first,last,result,op); first是容器的首迭代器last为容器的末迭代器result为存放结果的容器op为要进行操作的一元函数对象或sturct、class。 transform(first1,last1,first2,result,binary_op); first1是第一个容器的首迭代 器last1为第一个容器的末迭代器first2为第二个容器的首迭代器result为存放结果的容器binary_op为要进行操作的二元函数 对象或sturct、class。 可调用对象与function c语言中有几种可调用的对象函数、函数指针、lambda表达式、bind创建的对象以及重载了函数调用运算符的类。 和其他对象一样可调用的对象也有类型。例如每个lambda有它自己唯一的未命名类类型函数及函数指针的类型则由其返回值类型和实参类型决定等等。 不同类型可能具有相同的调用形式 上面这些可调用对象分别对其参数执行了不同的算术运算。尽管它们的类型各不相同但是共享同一种调用形式int(int,int) 我们可以定义一个函数表用于存储指向这些可调用对象的“指针”。当程序需要执行某个特定的操作时从表中查找该调用的函数。 函数表可以很容易的通过map来实现。我们的map可以定义成如下形式 //构建从运算符到函数指针的映射关系其中函数接受两个int、返回一个int mapstring,int(*)(int,int)binops;我们可以按照下面的形式将add的指针添加到binops中 binops.insert({,add});//{,add}是一个pair但是我们不能将mod或者divide存入binops中因为mod是个lambda表达式而每个lambda有它自己的类类型该类型于存储在binops中的类型不匹配。 binops.insert({%,mod});//错误mod不是一个函数指针我们可以使用一个名为function的新的标准库类型解决上述问题function定义在functional头文件中下表列出了function定义的操作 function是一个模板和我们使用过的其他模板一样当创建一个具体的function类型时我们必须提供额外的信息。示例如下 functionint(int,int)在这里我们声明了一个function类型它可以表示接受两个int、返回一个int的可调用对象。 functionint(int,int)f1 add; functionint(int,int)f1 divide(); functionint(int,int)f1 [](int i,int j){return i*j};//f1(4,2): 6 //f2(4,2): 2 //f3(4,2): 8使用这个function我们可以重新定义map: mapstring,functionint(int,int)binops;我们能把所有可调用对象包括函数指针、lambda或者函数对象在内都添加到这个map中 mapstring,functionint(int,int)binops{ {,add}, //函数指针 {-,std::minusint()}, //标准库函数对象 {/,divide()}, //用户定义的函数对象 {*,[](int i,int j){return i*j}}, //未命名的lambda {%,mod}, //命名的lambda }调用操作 binops[](10,5); //调用add(10,5)重载的函数与function 我们不能直接将重载函数的名字存入function类型的对象中。 重载、类型转换与运算符 类型转换运算符 类型转换运算符是类的一种特殊成员函数它负责将一个类类型的值转换成其他类型。类型转换函数的一般形式如下所示 operator type()const;其中type表示某种类型。类型转换运算符可以面向任意类型除了void之外进行定义只要该类型能作为函数的返回类型。因此我们不允许转换成数组或者函数类型但允许转换成指针包括数组指针及函数指针或者引用类型。 一个类型转换函数必须是类的成员函数它不能声明返回类型形参列表也必须为空。类型转换函数通常应该是const。 定义含有类型转换运算符的类 class SmallInt { public:SmallInt(int i 0) :val(i) {}operator int()const { return val; }void print() { cout val endl; } private:size_t val; };//测试代码SmallInt s1;s1 4;s1.print();cout s1 5 endl;s1 3.5;s1.print();cout s1 5 endl;输出结果 4 9 3 8因为类型转换运算符是隐式执行的所以无法给这些函数传递实参当然也就不能在类型转换运算符的定义中使用任何形参。同时尽管类型转换函数不负责指定返回类型但实际上每个类型转换函数都会返回一个对应类型的值 显式的类型转换运算符 当类型转换运算符是显式的时候我们也能执行类型转换不过必须通过显式的强制类型转换才可以。 class SmallInt { public:SmallInt(int i 0) :val(i) {}explicit operator int()const { return val; }void print() { cout val endl; } private:size_t val; };//测试代码SmallInt s1;s1 4;s1.print();cout int(s1) 5 endl;s1 3.5;s1.print();cout int(s1) 5 endl;如果表达式被用作条件则编译器会将显式的类型转换自动应用于它。换句话说当表达式出现在下列位置时显式的类型转换将被隐式地执行 向bool的类型转换通常用在条件部分因此operator bool一般定义成explicit的。 避免有二义性的类型转换 如果类中包含一个或多个类型转换则必须确保在类类型和目标类型之间只存在唯一一种转换方式。否则的话我们编写的代码很可能会具有二义性。 在两种情况下可能产生多重转换路径。 两个类提供相同的类型转换例如当A类定义了一个接受B类对象的转换构造函数同时B类定义了一个转换目标是A类的类型转换运算符时我们就说它们提供了相同的类型转换。 类定义了多个转换规则而这些转换涉及的类型本身可以通过其他类型转换联系在一起。最典型的例子是算术运算符对某个给定的类来说最好只定义最多一个与算术类型有关的转换规则。 除了显式地向bool类型的转换之外我们应该尽量避免定义类型转换函数并尽可能地限制那些“显然正确”的非显式构造函数。
http://wiki.neutronadmin.com/news/69994/

相关文章:

  • 电子商务网站建设题wordpress搭建电子商城
  • 公司网站想维护服务器一线城市做网站工资有多少钱
  • 付费主题怎么永久使用搜索引擎优化特点
  • 章丘网站建设哪家好帝国做网站
  • 网文网站网站建设兼职平台
  • 做印刷网站公司沈阳网站建设开发设计公司
  • 计算机网络技术网站建设方向it外包公司可以进吗
  • 微网站如何做推广申请域名做网站
  • 怎样可以做网站手机oa办公系统下载
  • 有关建设网站的英语文献4.4.12 wordpress
  • 学校二级学院网站建设建筑行业最新资讯
  • 网站内链工作做足做网站比较好的数字
  • 1做网站的公司openwrt 网站开发
  • 网站如何做线上和线下推广天元建设集团有限公司管理工资发放
  • 网站开发网站运营怎么做wordpress 动态加载
  • 网站的按钮怎么做的wordpress百度云盘
  • 莆田个人仿牌外贸网站建设网站建设 算什么
  • vr成品网站源码在线观看建设工程公开招标网站
  • 制作网站问题和解决方法太原做网站排名
  • 公司网站建设开源平台查询关键词网站
  • 福建永安建设局网站合肥房产网最新楼盘
  • wordpress 启用多站点深圳专门做网站的公司有哪些
  • e想时代官方网站商城网站后续费用
  • 佛山网站设计中心成功网站管理系统
  • 企业网站内容策划嘉兴网络项目建站公司
  • 织梦网站图片不显示图片网站建设维护岗位职责
  • 花型图案设计网站网站开发国际化
  • 山大优秀网站建设2018年度淘宝怎么才能发布网站建设
  • 免费网站建站凡科建站国内html5网站案例
  • 在线购物网站建设的需求分析张家界网站开发