C++面向对象高级编程_侯捷(上1) class without pointer members

2 头文件与类的声明

头文件中的防卫式声明(guard)

complex.h

// 如果没有定义过 __COMPLEX__,向下执行定义的操作,如果定义过了,就不会执行后面的语句
// 这样就不会反复 include 的动作

#ifndef __COMPLEX__
#define __COMPLEX__

...

#endif

3 构造函数

初始化列表 / 赋值

要使用初始化列表的形式对成员变量初始化,而不是在函数体内部对成员变量赋值。因为初始化列表的执行效率高,并且是构造函数特有的。
构造函数有很多种,所以需要重载(overloading)

class Complex
{
public:
    Complex(double re=0, double im=0): re(r), im(m) {}
    // 此时不能写无参构造函数,因为编译不知道该调用哪个构造函数
    // Complex() {re=0; im=0}
private:
    double re;
    double im;
};

构造函数权限控制 public / private

构造函数一般都是 public 权限,因为在类外创建对象需要调用构造函数。
但是也有将构造函数设置为 private 权限,例如在 Singlton(一种设计模式)中,只允许有一个对象,不允许用户在类外自己随意创建对象。

class A
{
public:
    static A& getInstance();
    setup() { ... }
private:
    A();
    A(const A& rhs);
    ...
};

A& A::getInstance()
{
    static A a;
    return a;
}

4 参数传递与返回值

class 中的函数可以分为:改变数据内容,不改变数据内容。
如果不改变数据,就在函数后面加 const。
const类型的类对象,只能调用const的成员函数。

double real() const {return re;}

参数传递 传值 / 传引用

参数传递:pass by value vs. pass by reference(to const)
尽量不要pass by value,这样把实参整个数据都传给了形参,当实参占用很多内存时,值传递的效率会下降。
尽量使用pass by reference,相当于传指针,所以传数据非常快。

// pass by value
Complex(double r=0, double i=0): rm(r), im(i) {}
// pass by reference
Complex& operator += (const Complex&);

传引用可能导致实参发生改变,这样虽然传递速度变快了,但数据被破坏了,所以使用 const 修饰形参,可以保证实参数据不被改变。

返回值传递 传值 / 传引用

返回值传递:return by value vs. return by reference(to const)
返回值的传递也尽量 by reference

// return by reference
Complex& operator += (const Complex&);
// return by value
double real() const {return re;}

什么情况下才可以 pass/return by reference

之前将到过:

  1. 数据尽可能的放在 private 里面;
  2. 参数尽可能使用 reference 来传,根据情况选择 const(是否要改变实参的数据);
  3. 返回值也尽量以 reference 来传;
  4. 在类本体(class body)里面的函数,应该加 const 就要加;
  5. 构造函数尽量使用初始化列表。
  • 什么情况下可以 pass by reference
  • 什么情况下可以 return by reference
    绝对不可以返回 local objects
// do assignment plus

// 第一个参数将会被改变,第二个参数不会被改变
// 第一个参数指向的空间是函数执行前就存在的,函数执行完仍然存在,所以可以返回引用
// 如果将在函数体内创建的空间的数据的引用传出函数体外,就会出错(语法没错),因为函数结束后,这块空间就死亡了。
inline complex& __doapl(complex* ths, const conplex& r)
{
    ths->re += r.re;
    ths->im += r.im;
    return *ths;
}

friend(友元)

C++ 中的友元可以使用类的 private 成员
friend 打破了 C++ 的封装

相同 class 的各个 objects 互为 friends

public:
    int func(const Complex& param)
    {return param.re + param.im;}

5 操作符重载与临时对象

operator overloading(操作符重载-1,成员函数) this

所有成员函数隐藏带有一个参数(this),谁(哪个对象)调用这个函数,谁就是this。

传递者无需知道接收者是以 reference 形式接收。
即,实参不变形式,形参是pass by value / reference 都不影响,函数形参接收实参。写法都一样

typename() 创建临时对象,它的声明到下一行就结束了。

第5节末尾是对不带指针的类的总结

看到第7节:三大函数

posted @ 2023-02-28 22:28  听雨画船眠  阅读(16)  评论(0编辑  收藏  举报