c++面向对象高级编程 学习一 不带指针的类

复数类 complex 是一个不带指针的类,其声明如下:

class complex
{
public:
complex(double r=0,double i=0):re(r),im(i){}
complex& operator +=(const complex&);
double real()const{return re;}
double imag()const{return im;}

private:
double re,im;
friend complex& __doapl(complex *,const complex&);
}

对以上代码进行解释如下:

double re,im;

对类中的数据进行声明,即实部和虚部,类中的数据应该是private的,不能被其他类访问到,
在c++中访问类的私有成员变量主要通过:set/get接口,友元类,友元函数。

double real()const{return re;}
double imag()const{return im;}

函数若在类体内定义完成,则自动成为inline候选,在类体外,加inline关键字,则其可成为inline候选。当对程序进行编译时,若inline候选的程序比较简洁,编译器会将其按照inline进行处理,若inline候选的程序比较负责,则编译器不会将其按照inline处理。
上面的函数是常量成员函数,即,该函数不改变类中成员数据的内容,其中const的位置是在参数列表后,即在()后面,{}前面。在确定函数不改变数据内容的时候,一定要将函数写成常量成员函数的形式,即一定要加const。因为常量类只能调用常量成员函数,若函数不加const,则常量类调用该函数的时候就会出现错误,因为调用非常量成员函数,会改变类的成员数据,即与常量类自相矛盾。

complex(double r=0,double i=0):re(r),im(i){}
//re(r),im(i)是对参数进行初始化
complex(double r=0,double i=0){re=r;im=i;}
//对参数进行赋值

构造函数中要尽量使用值的初始化,而不是赋值,这样性能会更高。
构造函数也可放在类的private区域,此时使用构造函数创建类将是错误的,因为private不能被访问到,即不允许外界通过构造函数创建类,单例模式即是如此。

参数传递和返回值传递,尽量选择使用引用传递。因为值传递会将参数进行拷贝并传递,浪费空间,值传递不会改变原始数据。而引用传递,是参数的别名,不需要对数据进行拷贝,可提高程序的性能,引用传递会改变原始数据。
返回值传递,首先考虑引用传递,再考虑引用是否可行,若不可行,再选择值传递。返回值传递时,若传递的数据是函数中新定义的局部变量,此时要选择值传递,因为若选用引用传递的话,当这个类消失的时候,该函数以及其定义的局部变量均会消失,而当其局部变量作为引用传递的返回值依然存在时,则会出现问题。即,当一个函数进行操作后,将操作的结果在函数里新建了一个变量来保存这个结果时,这种情况就不能返回引用;当一个函数进行操作后,将操作的结果放在某个参数里进行返回的时候,可以返回引用。

操作符重载的一般格式如下:

函数类型 operator 运算符名称 (形参列表)
{
对运算符的重载处理
}
complex& operator +=(const complex&);

此处是对 += 进行操作符重载。此处参数是const complex&,其中const表示对该参数不进行修改,即可加const。此处还包含一个隐式参数,例如,c1+=c2,调用的即为c1.operator+=(c2),此处实现为:

inline complex&
__doapl(complex* ths, const complex& r)
{
ths->re += r.re;
ths->im += r.im;
return *ths;
}
inline complex&
complex::operator += (const complex& r)
{
return __doapl (this, r);
}

即,c1调用operator+=函数,c1作为隐式参数,和c2调用__doapl()函数,并将最后的操作结果作为引用传递传回c1。

当操作符重载不作为成员函数时,就没有隐式参数。例如:
此处返回值是值传递,是因为对数据进行操作后,将返回结果保存在一个新建的变量中进行返回的,因此用值传递。可根据参数的不同进行重载。

complex operator +(const complex& x,const complex& y);
complex operator +(const complex& x,double y);
complex operator +(double x,const complex& y);
complex operator +(const complex& x); //例如:正号的作用

对输出函数进行重载:
此处也是选择非成员函数的方式,因为此时直接调用cout<<c1即可进行输出函数。
如果选择成员函数的形式,则调用方式则变为:c1<<cout,与常用方式不同。
返回值是ostream&的原因是:调用cout<<c1<<c2时不会出错,另外,参数ostream& os不是const的原因是,代码对os进行了改变。

#include <iostream.h>
ostream& operator << (ostream& os,const complex& x)
{
return os << '(' << real (x) << ','<< imag (x) << ')';
}
发布了5 篇原创文章 · 获赞 0 · 访问量 153

猜你喜欢

转载自blog.csdn.net/weixin_43116900/article/details/104656685