Skip to content

约 840 个字 66 行代码 预计阅读时间 5 分钟

this指针

  • 成员函数通过this指针访问调用它的那个对象
  • this形参是隐式定义的;this是一个常量指针

const成员函数

  • 默认情况下,this的类型是指向类类型非常量版本的常量指针
  • 需要将this声明为指向常量的指针
C++
std::string isbn() const {return this->bookNo;}

构造函数

  • 只有类没有声明任何构造函数时,编译器才会自动生成默认构造函数

=default含义

  • 作用完全等同于之前使用的合成默认构造函数

class和struct

  • 希望定义的类的所有成员是public时,使用struct
  • 希望成员是private的,使用class

友元

  • 类允许其他类或者函数访问它的非公有成员
  • 友元函数只能出现在类定义的内部

类的其它特性

  • 成员函数作为内联函数
  • 重载成员函数
  • 可变数据成员:即使是const对象成员,该值仍可改变
C++
class Screen {
public:
    void some_member() const;
private:
    mutable size_t access_ctr;
};
void Screen::some_member() const
{
    ++access_ctr;
}
  • 从const成员函数返回*this:是一个const对象

  • 基于const的重载

C++
class Screen {
public:
    Screen &display(std::ostream &os)
            {do_display(os); return *this;}
    const Screen &display(std::ostream &os) const       
            {do_display(os); return *this;} // 常量对象调用的函数
private:
    void do_display(std::ostream &os) const {os << contents;}
};

友元深入

  • 类之间的友元
  • 令成员函数作为友元

友元声明

  • 在类内部定义该函数,必须在类外部提供相应的声明使得函数可见
C++
struct X {
  friend void f() {}
  X() {f();}    // error: f is not be declared
  void g();
  void h();
};

void X::g() {return f();}   // error: f is not be declared
void f();
void X::h() {return f();}   // right!

名字查找和类的作用域

  • 编译器处理完类中的全部声明才处理成员函数的定义(如果在类中为查找到名字,到类作用域外层继续寻找)
  • 类型名一般定义在类开始处

构造函数再探

  • 使用构造函数初始值:效率问题,有些数据成员必须被初始化
  • 尽可能避免用某些成员初始化其它成员

隐式的类类型转换

  • 只允许一步转换,将字面值转换为string,类的默认构造函数将生成string类型的类
  • 抑制构造函数定义的隐式转换:explicit只用于直接初始化

聚合类

  • 成员均为public
  • 没有任何构造函数
  • 没有类内初始值
  • 没有基类和虚函数

字面值常量类

  • 数据成员均是字面值的聚合类
  • 另一种
  • 数据成员是字面值
  • 类中至少包含一个constexpr构造函数
  • 类内初始值是一个常量表达式
  • 必须使用析构函数的默认定义,该成员负责销毁类的对象
C++
class Debeg {
public:
    constexpr Debug(bool b = true): hw(b), io(b), other(b){}
    constexpr bool any() {return hw || io || other;}
    ...
private:
    bool hw;
    bool io;
    bool other;
};

类的静态成员

  • 不包含this指针,也不能声明成const,也不能再内部使用this指针

  • 必须在类的外部定义和初始化每个静态成员

  • (静态常量成员)类的内部提供了一个初始值,类外成员的定义不能在指定一个初始值了

  • 静态成员可以作为默认实参;而非静态数据成员本身是对象的一部分,不能作为默认实参

  • 可以访问类的私有成员

C++
class Account {
public:
    void calculate() {amount += amount*interestRate;}
private:
    static double interrestRate;
    void initRate(double newRate);
};

double Account::interestRate = initRate();
  • 定义静态成员函数可以在类内也可以在类外;static关键字只出现在类内

inline(内联)函数

  • 在类内定义的函数自动成为内联函数
C++
// ctors放在private
// 单例模式
class A {
public:
    static A& getInstance();
    setup(){}
private:
    A();
    A(const A& rhs);
};

A& A::getInstance()
{
    static A a;
    return a;
}
  • class with pointer members必须有拷贝构造函数和拷贝赋值运算符