【關鍵字】c++關鍵字


1. alignas (c++11)

設置類和struct的字節對齊方式

默認取值是:  2n : 0, 1, 2, 4 , 6, 8.....

2. alignof

區分sizeof(), alignof得到字節對齊的字節數

#include <iostream>
using namespace std;


//對結構體或類進行表示, 設置對齊方式為8字節
struct alignas(8) S {};

//struct alignas(1) U { S s; }  // warning

//有字節對齊(以4字節為對齊方式)
struct Foo
{
    int i;
    float f;
    char c;
};

struct Empty {};

struct alignas(64) Empty64 {};

struct alignas(1) Double {
    double d;
};

//以四字節為對齊方式, 即sizeof(Obj) == 8
struct Obj {
    char a;
    int b;
};


void alignInfo()
{
    cout << "sizeof(Obj)        : " << sizeof(Obj)      << endl; // 8
    cout << "alignof(Obj)       : " << alignof(Obj)     << endl; // 4
    cout << "sizeof(Foo)        : " << sizeof(Foo)      << endl; // 12
    cout << "sizeof(Double)     : " << sizeof(Double)   << endl; // 8
    cout << "sizeof(Empty64)    : " << sizeof(Empty64)  << endl; // 64

    cout << "\n";

    cout << "Alignment of " << endl;
    cout << "- char             : " << alignof(char)    << endl; // 1
    cout << "- pointer          : " << alignof(int*)    << endl; // 8
    cout << "- class Foo        : " << alignof(Foo)     << endl; // 4
    cout << "- empty class      : " << alignof(Empty)   << endl; // 1
    cout << "- alignas(64) Empty: " << alignof(Empty64) << endl; // 64
    cout << "- alignas(1) Double: " << alignof(Double)  << endl; // 8
}


int main()
{
    alignInfo();

    return 0;
}

3. auto (c++11)

#include <iostream>
using namespace std;

double add(double a, double b)
{
    return a + b;
}

double get_fun(int a)
{
    return a;
}

void showAuto()
{
    int aa = 1 + 2;
    auto a = 1 + 2;
    cout << "type of a: " << typeid(a).name() << endl;

    auto b = add(1, 1.2);
    cout << "type of b: " << typeid(b).name() << endl;

    auto c = {1, 2};
    cout << "type of c: " << typeid(c).name() << endl;

    auto my_lambda = [](int x) { return x + 3; };
    std::cout << "my_lambda: " << my_lambda(5) << endl;

    auto my_fun = get_fun(2);
    cout << "type of my_fun: " << typeid(my_fun).name() << endl;
    cout << "my_fun: " << get_fun(3) << endl;

}

int main()
{

    showAuto();
    return 0;
}

4. bitand 和 bitor 

#include <iostream>              
using namespace std;             
                                 
void showBitAndOr()              
{                                
    auto a = 3L;                 
    auto b = 4;                  
                                 
    //long                       
    auto c = a bitand b;  // &   
    auto d = a bitor b;   // |   
                                 
    cout << c << endl;           
                                 
    cout << d << endl;           
}                                
                                 
                                 
int main()                       
{                                
    showBitAndOr();              
                                 
    return 0;                    
}                                

5. constexpr: 常量表達式(c++11)

  • 用於編譯時的常量與常量函數。
  • 聲明為constexpr函數的意義是:如果其參數均為合適的編譯期常量,則對這個constexpr函數的調用就可用於 期望常量表達式 的場合(如模板的非類型參數,或枚舉常量的值)。
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;

int fact(int n)
{
    return n < 1 ? 1 : (n * fact(n - 1));
}

//編譯器在編譯器時, 就求出來返回的值了
constexpr int factorial(int n)
{
    return n <= 1 ? 1 : (n * factorial(n - 1));
}

template<int N>
struct NN {
    void print()
    {
        cout << N << endl;
    }
};

int main(int argc, char *argv[])
{

    //在編譯器編譯時調用的
    if (argc > 1) factorial(atoi(argv[1]));


    auto aa = fact(4);
    auto bb = factorial(2);
    char group[factorial(3)];   //編譯器在編譯時, 就求出來了

    NN<factorial(3)> nn;
    nn.print();

    return 0;

}

輸出: 6

6. const_cast(避免使用)

7. decltype指定符(c++11)

檢查實體的聲明類型或表達式的類型及值分類。

#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;


struct A {
    double x;
    A(double t) : x(t) {}

};

void testDecltype()
{
    A* a = new A(0);

    auto aa = a->x;          // aa : double 
    decltype(a->x) y;        // decltype(a->x) : double 
    decltype((a->x)) z = y;  // decltype((a->x)) : double&
    z = 23.5;
    cout << y << endl;       // 23.5

    //其他用法
}

//c++11, 后置返回類型, 返回值類型由 后面的表達式確定的
//返回值不損失任何精度
template<typename T, typename U>
auto add(T a, U b) -> decltype(a + b)
{
    return a + b;
}

template<typename T, typename U>
auto add(T a, U b) {
    auto c = a + b;
    //return c;   //返回值
    //return (c); //返回引用
    return c;
}  
   
int main(int argc, char **argv)
{  
    testDecltype();
   
    return 0;
}  

8. dynamic_cast轉換

沿繼承層級向上、向下及側向轉換到類的指針和引用。

#include <iostream>         
#include <cstdlib>          
#include <cstdio>           
using namespace std;        

struct Base                                           
{                                                     
    virtual ~Base() {}                                
};                                                    
                                                      
struct Derived : public Base                          
{                                                     
    virtual void name() {}                            
};                                                    
                                                      
void testDynatic_cast()                               
{                                                     
    Base *b1 = new Base();                            
    //擁有基類指針, base指針-->derived指針, 失敗      
    if (Derived *d = dynamic_cast<Derived *> (b1))    
    {                                                 
        cout << "donwcast from b1 to d successful\n"; 
        d->name();    // safe to call                 
    }                                                 
                                                      
    Base *b2 = new Derived();                         
    //成功, 因為b2的確指向derived                     
    if (Derived *d = dynamic_cast<Derived *> (b2))    
    {                                                 
        cout << "donwcast from b2 to d successful\n"; 
        d->name();    // safe to call                 
    }                                                 
}                                                     
                                                      
                                                      
int main(int argc, char **argv)                       
{                                                                                                     
                                                      
    testDynatic_cast();                               
                                                      
    return 0;                                         
}                                                     

9. explicit

struct A { A(int) { }      // 轉換構造函數
    A(int, int) { } // 轉換構造函數 (C++11)
    operator bool() const { return true; } }; 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 進行直接初始化
}

10. static_assert: 編譯時檢查

#include <iostream>
using namespace std;


template<typename T>
void func(T t)
{
    static_assert(alignof(T) == 4, "only for alignof 4");
}

int main()
{
    int a = 3;
        

    func(a);


    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM