说明符
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
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 进行直接初始化
}
//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_;
};