const member functions
为什么在函数名和函数体之间加 const
?
class complex{
public:
// 初始化列表
complex (double r = 0, double i = 0): re(r), im(i) {}
// 运算符重载
complex operator += (const complex);
// 为什么在函数名和函数体之间加 const ?
// 这里只是拿出来数据,并不会改变数据内容
// 不改变数据内容的函数,马上加上 const
// 该加一定要加
double real() const { return r; }
double imag() const { return i; }
private:
double re, im;
friend complex& __doapl (complex*, const complex&);
}
在设计接口的时候,需要加 const 的话,一定要加上 const。
不加上 const 会有什么后果?
// 加上 const 的情况,以下是 ok 的
{
complex c1(2, 1);
cout << c1.real();
cout << c1.imag();
}
// ??
/*
const 出现在了对象/变量的前面,表示其是不可以更改的
如果在这种情况下,complex 类中 real() 和 imag() 不加上 const ,
意思就是这两个函数可能会改 data
此时,类的 user 在这里加上 const 明确表示 c1 不可以更改的,
而 complex 类中却没有加 const,表示可以更改 data,这里就产生矛盾了
所以,编译器运行在这里会报错
*/
{
const complex c1(2, 1);
cout << c1.real();
cout << c1.imag();
}
规范化的 C++ 写法!!!
参数传递:
pass by value v.s. pass by reference(to const)
class complex{
public:
complex (double r = 0, double i = 0): re(r), im(i) {}
// & and const
complex operator += (const complex&);
double real() const { return r; }
double imag() const { return i; }
private:
double re, im;
// & and const
friend complex& __doapl (complex*, const complex&);
}
// 第一个参数传进来没有 const ??
ostream& operator << (ostream& os, const complex& x)
{
return os << '(' << real(x) << ',' << imag(x) << ')';
}
double 4个字节
尽量不要 pass by value
值传递
过去在 C 中可以传递指针:传递的东西太大了,怎么办呢?就把这个东西的地址传过去。指针 4 个字节,速度会很快。
C++ 中有 reference。
引用在底层就是一个指针,所以传引用就相当于传指针那么快,形式比指针漂亮!
所以我们可以的话,尽量所有的参数传递都传引用。(速度更快啊)
特例:字符一个字节,引用四个字节。为什么不穿字符的值呢?在这种情况下,也可以。
那么问题来了,我们传引用如果只是为了速度,但是并不想被修改,该怎么办呢?
传引用/指针可能会修改原始数据,但是我们不想原始数据被改动,那么我们可以加上 const,这样的话如果实际情况发生修改的话,编译的时候就会出错。
返回值传递
return by value and return by reference(to const)
reference 也可以用于返回值的传递
传引用速度很快,就是传指针的速度。
返回值的传递尽量 Pass by Reference
class complex{
public:
complex (double r = 0, double i = 0): re(r), im(i) {}
// & and const
// 返回的类型:return by reference
// complex&
complex& operator += (const complex&);
// return by value
double real() const { return r; }
double imag() const { return i; }
private:
double re, im;
// & and const
// do assignment plus
// 返回的类型:return by reference
// complex&
friend complex& __doapl (complex*, const complex&);
}
// 第一个参数传进来没有 const
ostream& operator << (ostream& os, const complex& x)
{
return os << '(' << real(x) << ',' << imag(x) << ')';
}
friend
class complex{
public:
complex (double r = 0, double i = 0): re(r), im(i) {}
complex& operator += (const complex&);
double real() const { return r; }
double imag() const { return i; }
private:
// 实部和虚部 放在 private 中,表示不想让外界可以任意访问实部和虚部
// 外界访问实部和虚部可以通过 public 中的函数来获取
double re, im;
// 加 friend 表示该函数是 class 的 friend ,可以直接操作实部和虚部
// 这里是 __doapl 函数的声明
friend complex& __doapl (complex*, const complex&);
}
// 这是 __doapl 函数的定义
// 自由取得 friend 的 private 成员(并不需要通过某个函数)
inline complex&
__doapl (complex* ths, const complex& r)
{
ths->re += r.re;
ths->im += r.im;
return ths;
}
通过函数拿数据稍微慢一点, 通过 friend 是直接拿,会快一点。
可是 friend 破坏了 封装性,要设计者自己来权衡。
相同 class 的各个 object 互为 friends, 所以可以这样:
class complex{
public:
complex (double r = 0, double i = 0): re(r), im(i) {}
complex& operator += (const complex&);
double real() const { return r; }
double imag() const { return i; }
//
int func(const complex& param){
return param.re + param.im;
}
private:
double re, im;
};
{
complex c1(2, 1);
complex c2;
// 在这里竟然可以直接拿另外一个 object 中的 private 属性 ?!
c2.func(c1);
}
class body 外各种定义
什么情况下可以 pass by reference
什么情况下可以 return by reference
加不加 const ? 看情况。
构造函数的特殊语法: initialization list 尽量使用
什么时候不能 return by reference ?
c1 += c2 运算结果放在 c1,可以传引用出去。
c1 + c2 运算结果,必须放在函数新创建的新的东西里(local 变量),这时候就不是 返回 reference, 因为在函数内创建的那个东西,在函数调用结束就没有了,如果把引用传出去的话,会出问题。
网友评论