跳转至

说明符

1 final

  • 功能:
  • 限制虚函数不能在派生类中重写
  • 限制类不能被继承
  • 示例
struct Base
{
    virtual void foo();
};

struct A : Base
{
    void foo() final; // Base::foo is overridden and A::foo is the final override
    void bar() final; // Error: bar cannot be final as it is non-virtual
};

struct B final : A // struct B is final
{
    void foo() override; // Error: foo cannot be overridden as it is final in A
};

struct C : B // Error: B is final
{
};

2 override

  • 功能:指示虚函数重写自基类虚函数
  • 示例
struct A
{
    virtual void foo();
    void bar();
};
struct B : A
{
    void foo() const override; // Error: B::foo does not override A::foo
                               // (signature mismatch)
    void foo() override; // OK: B::foo overrides A::foo
    void bar() override; // Error: A::bar is not virtual
};

3 alignas和alignof

  • 功能:
  • alignas指定内存对齐字节数
  • alignof计算内存对齐字节数(注:alignof不是说明符,是运算符)
  • 示例
struct alignas(128) G1 {
    float f;
};
struct G2
{
    char c1;
    G1 g;
    char c2;
};
int main()
{
    printf("sizeof(G1)=%d  alignof(G1)=%d\n", sizeof(G1), alignof(G1));
    printf("sizeof(G2)=%d  alignof(G2)=%d\n", sizeof(G2), alignof(G2));
    return 0;
}
//输出结果
//sizeof(G1)=128  alignof(G1)=128
//sizeof(G2)=384  alignof(G2)=128
  • 上例中G1和G2结构的内存布局
1>class G1  size(128):
1>  +---
1> 0    | f
1>  +---
1>class G2  size(384):
1>  +---
1> 0    | c1
1>      | <alignment member> (size=127)
1>128   | G1 g
1>256   | c2
1>      | <alignment member> (size=127)
1>  +---

4 explicit

  • 功能:使构造函数或转换函数为显式,即它不能用于隐式转换和复制初始化。
  • 示例
struct A
{
    A(int) { }      // 转换构造函数
    A(int, int) { } // 转换构造函数 (C++11)
    operator bool() const { return true; }
    A& operator =(int) { return *this; }
};

struct B
{
    explicit B(int) { }
    explicit B(int, int) { }
    explicit operator bool() const { return true; }
};

int main()
{
    A a1 = 1;      // OK:复制初始化选择 A::A(int)
    A a2(2);       // OK:直接初始化选择 A::A(int)
    A a3{ 4, 5 };   // OK:直接列表初始化选择 A::A(int, int)
    A a4 = { 4, 5 }; // OK:复制列表初始化选择 A::A(int, int)
    A a5 = (A)1;   // OK:显式转型进行 static_cast
    if (a1);      // OK:A::operator bool()
    bool na1 = a1; // OK:复制初始化选择 A::operator bool()
    bool na2 = static_cast<bool>(a1); // OK:static_cast 进行直接初始化

//  B b1 = 1;      // 错误:复制初始化不考虑 B::B(int)
    B b2(2);       // OK:直接初始化选择 B::B(int)
    B b3{ 4, 5 };   // OK:直接列表初始化选择 B::B(int, int)
//  B b4 = {4, 5}; // 错误:复制列表初始化不考虑 B::B(int,int)
    B b5 = (B)1;   // OK:显式转型进行 static_cast
    if (b2);      // OK:B::operator bool()
//  bool nb1 = b2; // 错误:复制初始化不考虑 B::operator bool()
    bool nb2 = static_cast<bool>(b2); // OK:static_cast 进行直接初始化
}
  • explicit+常量表达式(C++20)
  • 示例
//c++20前
template<class T>
struct wrapper {
  template<class U, std::enable_if_t<std::is_convertible_v<U, T>>* = nullptr>
  wrapper(U const& u) : t_(u) {}

  template<class U, std::enable_if_t<!std::is_convertible_v<U, T>>* = nullptr>
  explicit wrapper(U const& u) : t_(u) {}

  T t_;
};
//C++20后
template<class T> 
struct wrapper { 
  template<class U> 
  explicit(!std::is_convertible_v<U, T>) 
  wrapper(U const& u) : t_(u) {} 

  T t_; 
};