1. 內存對齊
#pragma pack(push, 1) struct A { char a; int b; double c; char d[11]; }; #pragma pack(pop) #pragma pack(push, 2) struct B { char a; int b; double c; char d[11]; }; #pragma pack(pop) void main() { cout << sizeof(A) << endl; cout << sizeof(B) << endl; }

上面的代碼演示了采用#pragma pack()方法實現內存對其。接下來介紹C++11中相關內存對其的方法。
1.1 alignas
alignas指定內存對其大小,有時候我們希望不按照默認的內存對齊方式來對齊,這時我們可以用alignas來指定內存對齊。
在C++11中,只要是一個編譯期數值(#define, static const, template)都支持alignas,另外需要注意alignas只能改大不能改小,如果要改小可以使用上面提到的#pragma pack(1)
1.2 alignof和std::alignment_of
alignof用來獲取內存對齊大小,用法比較簡單:
A a;
cout << alignof(a) << endl;
alignof只能返回一個size_t,而std::alignment_of繼承自std::integral_constant,擁有value_type,type,value成員
cout << std::alignment_of<A>::value << endl; >>>> 1
cout << std::alignment_of<B>::value << endl; >>>> 2
1.3 std::aligned_storage
std::aligned_storage可以看成一個內存對其的緩沖區,原型如下:
template<std::size_t Len, std::size_t Align = /*default-alignment*/>
struct aligned_storage;
Len表示所存儲類型的sie,Align表示該類型的內存對齊大小
1.4 max_align_t和std::align
std::max_align_t用來返回當前平台的最大默認內存對齊類型,對於malloc返回的內存,其對齊和max_align_t類型的對齊大小應當是一致的。我們可以通過下面的方式獲得當前平台的最大默認內存對齊數:
std::cout << alignof(std::max_align_t) << std::endl;
std::align用來在一大塊內存中獲取一個符合指定內存要求的地址
char buffer[] = "......"; void *ptr = buffer; std::size_t space = sizeof(buffer) - 1; std::align(alignof(int),sizeof(char),pt,space);
2. 示例
2.1. optional類實現
// 實現boost中的optional類 // 該類可以存儲任意類型的數據 // int float string struct #pragma once using namespace std; template <typename T> class COptional { public: // alignof是vs2013ctp中才支持的版本,如果沒有該版本,用alignedment_of<T>::value代替 //typedef aligned_storage<sizeof(T), alignof(T)>::type AligendT; using AligendT = typename aligned_storage<sizeof(T), alignment_of<T>::value>::type; COptional(){} COptional(const T &t) { Create(t); } COptional(const COptional& other) { if (other.IsInit()) { Assign(other); } } ~COptional() { if (IsInit()) { Destroy(); } } const T & operator*() const { if (IsInit()) { return *((T *)(&m_Data)); } cout << "is not init!" << endl; } // 根據參數創建 template<typename ...ARGS> void Emplace(ARGS&& ...Args) { Destroy(); Create(forward<ARGS>(Args)...); } private: template <typename ...ARGS> void Create(ARGS&& ...Args) { new (&m_Data) T(forward<ARGS>(Args)...); // placement new 創建 m_bInit = true; } // 銷毀緩沖區對象 void Destroy() { if (m_bInit) { m_bInit = false; ((T *)(&m_Data))->~T(); } } bool IsInit() const { return m_bInit; } void Assign(const COptional& other) { if (other.IsInit()) { Destroy(); new (&m_Data) (T)*((T*)(&other.m_Data)); m_bInit = true; } Destroy(); } private: AligendT m_Data; bool m_bInit = false; };
2.2. 惰性求值類lazy類實現
#pragma once #include<type_traits> #include<boost\optional.hpp> using namespace std; // 實現懶惰求值類lazy template<typename T> class CLazy { public: CLazy(){} template<typename FUN, typename ...ARG> CLazy(FUN &fun, ARG ...args) { std::cout << "參數個數:" << sizeof ...(args) << std::endl; m_fun = [&fun, args...]{return fun(args...); }; } T &Value() { if (!m_Value.is_initialized()) { m_Value = m_fun(); // 隱士轉換 } return *m_Value; } bool IsCreated() const { return m_Value.is_initialized(); } private: std::function<T()> m_fun; boost::optional<T> m_Value; };
3. 測試
#include "stdio.h" #include "lazy.h" #include<iostream> using namespace std; #include "optionalex.h" int foo(int x) { cout << "函數名:" << __FUNCTION__ << endl; return 2 * x; } float fooadd(int x, int y, float z) { cout << "函數名:" << __FUNCTION__ << endl; return x + y+z; } template<typename FUN, typename ...ARG> CLazy<typename result_of<FUN(ARG...)>::type> lazy(FUN && fun, ARG && ...args) { return CLazy<typename result_of<FUN(ARG...)>::type>(forward<FUN>(fun), forward<ARG>(args)...); } struct test { int a; float b; test(int aa, float bb) :a(aa), b(bb){} friend ostream& operator<<(ostream& os, const test& other) { os << other.a << " " << other.b << endl; return os; } }; void main() { cout << "COptional類測試1,當對象沒初始化:" << endl; COptional<int> op1; cout << "輸出:" << *op1 << endl; cout << "COptional類測試2,int類型:" << endl; COptional<int> op2 = 99; cout << "輸出:" << *op2 << endl; cout << "COptional類測試3,float類型:" << endl; COptional<float> op3 = 12.453; cout << "輸出:" << *op3 << endl; cout << "COptional類測試4,struct類型:" << endl; COptional<test> op4 = test(8, 9.8); cout << "輸出:" << *op4 << endl; cout << "lazy類測試:" << endl; CLazy<int> lazy1(foo, 2); cout << lazy1.Value() << endl; CLazy<float> lazy22(fooadd, 2, 4, 6.2); cout << lazy22.Value() << endl; cout << lazy([](int a, int b){return a + b; }, 10, 22).Value() << endl; }

