C++11新特性之字节对齐、多参数模版、placement new

1.内存对齐上面的代码演示了采用#pragmapack()方法实现内存对其。接下来介绍C++11中相关内存对其的方法。1.1alignasalignas指定内存对其大小,有时候我们希望不按

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

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;
}

C++11新特性之字节对齐、多参数模版、placement new

  上面的代码演示了采用#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;
}

C++11新特性之字节对齐、多参数模版、placement new

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120130.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 卡方检验,U检验,t检验,F检验

    卡方检验,U检验,t检验,F检验卡方检验:主要用于等级资料。t检验:适用于计量资料、正态分布、方差具有齐性的两组间小样本比较。包括配对资料间、样本与均数间、两样本均数间比较三种,三者的计算公式不能混淆。也可以这样理解主要是用于小样本(样本容量小于30)的两个平均值差异程度的检验方法。U检验:检验应用条件与t检验基本一致,只是当大样本时用U检验,而小样本时则用t检验,t检验可以代替U检验。t检验和就是统计量为t,u的假…

    2022年6月19日
    43
  • H264/AVC视频解码时AVC1和H264的区别 .

    H264/AVC视频解码时AVC1和H264的区别 .我一直疑问为什么有些视频解码时显示格式是:H264,大部分又是:AVC1我在搜索编程资料时在微软的msdn上发现的:原文:http://msdn.microsoft.com/en-us/library/dd757808(v=vs.85).aspxFOURCC:AVC1  描述:H.264bitstreamwithoutstartcodes.FOURCC:H264  描述

    2022年6月18日
    25
  • 三层架构(我了解并详细分析)

    三层架构(我了解并详细分析)

    2021年12月31日
    45
  • caioj 1079 动态规划入门(非常规DP3:钓鱼)(动规中的坑)「建议收藏」

    caioj 1079 动态规划入门(非常规DP3:钓鱼)(动规中的坑)「建议收藏」caioj 1079 动态规划入门(非常规DP3:钓鱼)(动规中的坑)

    2022年4月20日
    42
  • Landsat8 OLI数据不同波段组合作用

    Landsat8 OLI数据不同波段组合作用OLI波段合成 R、G、B 主要用途 4、3、2 自然真彩色 7、6、4 城市 5、4、3 标准假彩色图像、植被 6、5、2 农业 7、6、5 穿透大气层 5、6、2 健康植被 5、6、4

    2022年7月23日
    21
  • 智能家居、智慧社区与智慧城市的关系_智能家居有哪些

    智能家居、智慧社区与智慧城市的关系_智能家居有哪些物联网技术可让智能家居应用变得更方便。过去几年年可说是智能家居生态链成形的关键年,许多科技大厂如Google并购Nest/Dropcam、三星并购SmartThings等,或是合作建立物联网联盟,如Qualcomm建立Allseen、Intel及三星主导OIC等,积极建立智能家居管理平台,提供有意进军智能家居的业者API,整合第三方软硬件资源,…

    2022年10月17日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号