第四节 参数传递与返回值
把构造函数放在private区内。看起来有一点奇怪,这个意思就是:函数不可被外界调用。
constructor(ctor)构造函数被放在private区,也就是,不允许被外界创建对象。
这种写法叫singleton,是有需求的。
常量成员函数(const member functions)
real()函数后跟着const ,则不会改变类内部的数据。不会改变数据内容的,需要加上const 。
当外部定义虚数类为const时,倘若我们的成员函数没有加const,相当于告诉编译器:我可能会修改这个成员的数据。那么,就会报错。此时,需要将对应的成员函数定义为const,相当于告诉编译器我们不会在这个函数中改变任何一个数据。
参数传递:(pass by value / pass by reference(to const))
complex(double r = 0, double i = 0)
: re(r), im(i)
{ }
//这里的double后面的,是传值调用。
complex& operator += (const complex&)
//这里的是传址调用,而且保持地址不变
ostream&
operator << (ostream& os, const complex& x)
//这里是传址调用,只不过并非是对const的
pass by value 传递对应类型的数据。
实际上,尽量不要pass by value,因为传值调用涉及到将变量打包后提供。所以我们要尽量通过pass by reference.像传址调用,引用在底层是一种指针,所以传引用相当于传递指针。
尽量所有的传递都传引用。
而且,在传递引用的时候,如果不希望发生修改。则,传递引用,并且传递的是const的一个引用。如上述const complex&。若在后续过程发生修改,则会编译出错。
返回值的传递也尽量By reference
complex& operator...//return by reference
double real() //return by value
友元(friend)
类中的友元函数,是可以拿有类中private部分数据的。外界要取实部虚部,是不能直接访问封装内部的数据的,而若我们要调用private部分的数据,则我们应当声明一些友元函数。
inline complex&
_doapl (complex* ths, const complex& r)
{
ths->re += r.re;
ths->im += r.im;
return *ths;
}
这里我们可以直接调用r的内部数据re、im,是因为_doapl是友元函数,可以对封装的部分进行数据加工。如果非朋友,则必须通过函数调用,会慢一点。
相同class的各个objects互为friends(友元)
所以,在public中定义的函数倘若直接引用private的数据,也是可以的。因为公开部分的函数也是class中的一个类,则也可以为友元,所以可以引用其中的对象。
什么情况不能return by reference?
函数中生成的数据无法存储在已有的地址/指针对应的变量中,如a+b存储在一个local临时变量c中,就不能返回引用了。而是需要传值。若函数生成的数据最终可以被存储在某个地址对应的变量中,则可以传地址。