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::value << endl; >>>> 1
cout << std::alignment_of::value << endl; >>>> 2
1.3 std::aligned_storage
std::aligned_storage可以看成一个内存对其的缓冲区,原型如下:
template
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<boostoptional.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;
}
原文链接: https://www.cnblogs.com/xiaobingqianrui/p/9068226.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/274497
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!