类在编写过程中的一些注意事项

在编写类的时候我们要很好的把握细节问题,不仅仅要去避免一些明显的错误,更多的是如何形成良好的编程风格。下面我们将从下面的一个例子分析类的编写技巧:

class Complex

{

public:

Complex(double real,double imaginary = 0):_real(real),_imaginary(imaginary){ }

void operator+(Complex other)

{

_real =_real +other._real;

_imaginary = _imaginary + other._imaginary;

}

void operator<<(ostream os)

{

os << "(" << _real << "," << _imaginary << ")";

}

Complex operator++()

{

++_real;

return *this;

}

Complex operator++(int)

{

Complex temp = *this;

++_real;

return temp;

}

private:

double _real,_imaginary;

}

1、我们要当心在隐式类型转换中产生的隐含临时对象。避免这个问题的一个好方法就是,尽可能的在构造函数中进行显示的类型转换,并要避免编写类型转换运算符。

由于上述类中的构造函数的第二个参数有默认值,因此这个函数也可当成是单参数的构造函数来使用,这也意味着可以进行从double类型到Complex类型的隐式转换。要注意这种类型转换可能并不总是我们所希望的。

2、在传递参数对象时,我们应该优先选择const&的方式,而不是传值方式。例如:

void operator+(Complex other)在传递参数时将会有临时对象的产生,执行效率会降低

3、我们应该优先选择“a op=b”这种写法,而不是“a = a op b”(这里的op表示的是某个运算符)。这种写法更为清晰,而且效率也更高。

为什么operator+=的效率会更高?原因就在于这个运算符是直接对其左边的对象进行运算,并且返回的是一个引用而不是临时对象。而operator+则必须返回一个临时对象。例如:

T& T::operator+=(const T& other)

{

//...

return *this;

}

const T operator+(const T& a,const T& b)

{

T temp(a);

temp+=b;

return temp;

}

我们要注意的是运算符+和+=之间的关系。前者是通过后者来实现的,这不仅是为了实现代码的简洁性,也是为了保证代码的一致性。注意,为了防止程序员编写出像“a+b = c”这样的表达式,所返回的临时对象的类型应该是“const Complex”(而不是Complex),这就是为什么上面的operator+中返回的是const T的原因。

4、在C++标准中规定:必须将运算符=、( )、[ ]和->定义为成员函数,而在类中定义的new、new[]、delete和delete[]等运算符函数必须是静态成员函数。对于其他的运算符函数:如果运算符函数时用于对流进行I/O的operator>>或者operator<<;或者如果需要对其左参数进行类型转换;或者如果可以通过类的公有接口来实现,那么将这个函数定义为非成员函数(在前两种情况中,如果需要的话也可以被定义为友元函数)。如果运算符函数需要实现虚函数的行为,那么请增加一个虚成员函数来提供虚函数的行为,那么请增加一个虚成员函数来提供虚函数的行为,并用这个虚成员函数来实现运算符函数。否则将运算符函数定义为成员函数。

5、operator<< 不应该被定义为成员函数。并且,非成员函数operator<<应该使用成员函数(通常是虚函数)来实现,并且这个成员函数的功能就是进行流输出。更进一步,operator<<应该返回一个“ostream&”类型的应用,并且所应用的就是这个流对象,这是为了实现链式操作。

6、前置递增运算符应该返回一个非常量的引用,这不仅使客户代码能够以更直观的方式来编写,而且还避免了不必要的低效率。在后置递增运算符函数中应该返回一个常量值。这种做法可以防止对返回的对象进行修改,从而避免了想“a++++”这样的问题代码。并且为了保持代码的一致性,我们应该使用前置递增来实现后置递增。

7、要避免使用保留名字。在C++标准库的实现中保留了一些带有前导下划线的标识符,这些保留的标识符是很难记住的,因此,最好是根本不要使用前导下划线。

经过以上的分析,我们修改后的类为:

class Complex

{

public:

explicit Complex(double real,double imaginary = 0):_real(real),_imaginary(imaginary){ }

Complex& operator+=(const Complex& other)

{

_real += other._real;

_imaginary += other._imaginary;

return *this;

}

Complex& operator++()

{

++_real;

return *this;

}

const Complex operator++(int)

{

Complex temp (*this);

++_real;

return temp;

}

ostream& Print(ostream& os) const

{

return os << "(" << real_ <<","<< imaginary_ << ")";

}

private:

double real_,imaginary_;

}

const Complex operator+(const Complex& lhs,const Complex& rhs)

{

Complex ret(lhs);

ret+=rhs;

return ret;

}

ostream& operator<<(ostream& os,const Complex& c)

{

return c.Print(os);

}



时间: 2024-10-11 21:14:24

类在编写过程中的一些注意事项的相关文章

Selenium2学习-018-WebUI自动化实战实例-016-自动化脚本编写过程中的登录验证码问题

日常的 Web 网站开发的过程中,为提升登录安全或防止用户通过脚本进行黄牛操作(宇宙最贵铁皮天朝魔都的机动车牌照竞拍中),很多网站在登录的时候,添加了验证码验证,而且验证码的实现越来越复杂,对其进行脚本识别的难度也越来越高.这对我们自动化脚本编写带了非常的不便,那么如何解决登录时的验证码问题呢?经常有初学自动化脚本编写的小主们问及此问题. 此文主要针对如何解决自动化测试脚本中含登录态的操作问题,即如何降低验证码对自动化脚本编写过程中的解决方法进行分析和解决,并以实例演示(基于易迅网易迅账号登录)

使用MatLab过程中的一些注意事项

1.如果输入单行后直接按回车,如 则直接显示结果如下 2.如果希望输入多行,则需要在行尾使用"Shift"+"Enter"组合键来换行 3.如果输入多行,但只需显示最后一条结果,可以在之前的语句末尾使用";" //未完待续 使用MatLab过程中的一些注意事项

Python爬虫(图片)编写过程中遇到的问题

最近我突然对网络爬虫开窍了,真正做起来的时候发现并不算太难,都怪我以前有点懒,不过近两年编写了一些程序,手感积累了一些肯定也是因素,总之,还是惭愧了.好了,说正题,我把这两天做爬虫的过程中遇到的问题总结一下: 需求:做一个爬虫,爬取一个网站上所有的图片(只爬大图,小图标就略过) 思路:1.获取网站入口,这个入口网页上有很多图片集合入口,进入这些图片集合就能看到图片链接了,所以爬取的深度为2,比较简单:2.各个子图片集合内所包含的图片链接有两种形式:一种是绝对图片路径(直接下载即可),另一种的相对

ABAP程序编写过程中怎么提高程序执行效率一

影响ABAP程序的运行效率主要是在程序中大量数据的取得,如果取数不得方法,很影响报表的运行效率,所有优化ABAP程序主要是优化数据取数的方法.下面这几点可以有效的提高取数的效率,从而来提高程序的运行效率. 1.选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 drivingtable)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.如果有3个以上的表连

配置Office 365单点登录过程中的一些注意事项 (稍后配图)

这些天一直在整O365单点登录的问题,其中涉及到了很多知识点,其中以ADFS,CA为主吧,IIS为辅.下面我就把这些天积累的一些经验写下来备用. 1. 申请证书不一定要通过“证书颁发机构Web注册”,直接在mmc控制台即可进行,详见我的另一篇博文. 2. 如果通过http://server/certsrv的方式申请证书,需要注意以下几点:2.1 http://server/certsrv这个网站需要启用HTTPS,否则“证书模板”下拉列表出不来.但是实验过程中遇到没启用照样可以申请的事情,不清楚

后台管理系统--编写过程中遇到的问题总结

1.父子组件间的传值与vuex 起初,弹框的显示我都用了vuex来实现,虽然可以实现但没有真正发挥vuex是用处,属于滥用了,直到大牛指点说vuex一般都用来处理接口请求回来的复用性高的数据,而不是什么都用vuex,弹框就直接使用父子之间的传值就可以了(vuex--为了没有直接关系的组件间的数据共享,用在调用接口上即可,不要滥用). ① 父子组件间的传值 父--子:父在子组件标签里通过:xxx="xxx"的方式传给子组件,子组件通过props接收,如若要改变接收过来的值就在计算属性里改

解决jsp编写过程中换另一个jsp可以忽视登录过程

在编写web大作业时发现,如果直接更换jsp地址,可以直接进入管理员界面. 为了解决这一问题,首先编写一个check文档: <% HttpSession sessi= request.getSession(); String login = (String) sessi.getAttribute("login"); if( !"login".equals(login)){ request.setAttribute("err","未

LoadRunner接口脚本编写过程中遇到的问题及分享

工作中需要接口测试,报文编辑器一条条手工发费时费力,因此考虑利用web_submit_data函数POST方法进行报文编辑.在报文编辑中主要遇到了三个问题,其中一个问题耗时两天查到问题所在,在这里与大家一块分享. 问题1:我们支持报文头报文体分开的报文和只有一个xml格式的报文并行.因此对只有一个xml格式的报文编辑完后,在LR执行成功,但在系统中没查到相关日志.排查问题时多次编写了报文,并对web_submit_data函数的配置进行更改.对参数化的变量进行多次检查.......,就在今天早上

LoadRunner接口脚本web_submit_data编写过程中遇到的问题及分享

工作中需要接口测试,报文编辑器一条条手工发费时费力,因此考虑利用web_submit_data函数POST方法进行报文编辑.在报文编辑中主要遇到了三个问题,其中一个问题耗时两天查到问题所在,在这里与大家一块分享. 问题1:我们支持报文头报文体分开的报文和只有一个xml格式的报文并行.因此对只有一个xml格式的报文编辑完后,在LR执行成功,但在系统中没查到相关日志.排查问题时多次编写了报文,并对web_submit_data函数的配置进行更改.对参数化的变量进行多次检查.......,就在今天早上