类对象数组初始化(三种方法)

2023-10-31

参考自《More Effective C++中文版》


    类对象数组初始化参考自《More Effective C++中文版》


    类对象数组初始化


    如有一个如下类:
    class EquipmentPiece {
    private:
        int IDNumber;
    public:
        EquipmentPiece(int IDNumber) : IDNumber(IDNumber) {};
    };


 


    以下列出几种初始化的方法:
    <一>、对象数组
        int ID1, ID2, ID3;
        EquipmentPiece bestPieces[] = { EquipmentPiece(ID1), EquipmentPiece(ID2), EquipmentPiece(ID3) };


    注意:
        EquipmentPiece bestPieces[10];    //no appropriate default constructor available
        EquipmentPiece *bestPieces = new EquipmentPiece[10];    //no appropriate default constructor available
    当然,如果你将构造函数参数全都设了默认值,以上两种写法也成功,如将类中构造函数修改如下:
        ...
        EquipmentPiece(int IDNumber = 0) : IDNumber(IDNumber) {};
        ...




    <二>、指针数组
        typedef EquipmentPiece* PEP;    //PEP是个指向EquipmentPiece的指针


        PEP bestPieces[10];                //等同于 PEP *bestPieces = new PEP[10];


        //然后初始化
        for(int i = 0; i < 10; i++){
            bestPieces[i] = new EquipmentPiece( IDNumber );
        }


    注意:
        要记得将此数组所指的所有对象删除。如果忘了会产生资源泄露。还有就是该方法与对象数组相比需要额外内存用于存放指针。(过度使用内存 这一问题可以避免,见第三种方法)




    <三>、使用placement new
        方法是:先为此数组分配raw memory,然后使用"placement new"在这块内存上构造EquipmentPiece objects;


        //分配足够的raw memory,给一个预备容纳10个EquipmentPiece objects的数组使用
        void *rawMemory = operator new(10*sizeof(EquipmentPiece));


        //让bestPieces指向此内存,使这块内存被视为一个EquipmentPiece数组
        EquipmentPiece *bestPieces = reinterpret_cast<EquipmentPiece*>(rawMemory);


        //利用"placement new"构造这块内存中的EquipmentPiece objects。
        int IDNumber = 0;
        for(int i = 0; i < 10; i++){
            new (&bestPieces[i]) EquipmentPiece( IDNumber );
        }


    注意:该方法维护比较困难。在数组内对象结束生命时,要以手动方式调用destructors,最后还得调用operator delete释放raw memory。
        //将bestPieces中对象以构造次序的反序析构掉
        for(i = 0; i < 10; i++){
            bestPieces[i].~EquipmentPiece();
        }


        //释放raw memory
        operator delete (rawMemory);


    如有一个如下类:
    class EquipmentPiece {
    private:
        int IDNumber;
    public:
        EquipmentPiece(int IDNumber) : IDNumber(IDNumber) {};
    };


 


    以下列出几种初始化的方法:
    <一>、对象数组
        int ID1, ID2, ID3;
        EquipmentPiece bestPieces[] = { EquipmentPiece(ID1), EquipmentPiece(ID2), EquipmentPiece(ID3) };


    注意:
        EquipmentPiece bestPieces[10];    //no appropriate default constructor available
        EquipmentPiece *bestPieces = new EquipmentPiece[10];    //no appropriate default constructor available
    当然,如果你将构造函数参数全都设了默认值,以上两种写法也成功,如将类中构造函数修改如下:
        ...
        EquipmentPiece(int IDNumber = 0) : IDNumber(IDNumber) {};
        ...




    <二>、指针数组
        typedef EquipmentPiece* PEP;    //PEP是个指向EquipmentPiece的指针


        PEP bestPieces[10];                //等同于 PEP *bestPieces = new PEP[10];


        //然后初始化
        for(int i = 0; i < 10; i++){
            bestPieces[i] = new EquipmentPiece( IDNumber );
        }


    注意:
        要记得将此数组所指的所有对象删除。如果忘了会产生资源泄露。还有就是该方法与对象数组相比需要额外内存用于存放指针。(过度使用内存 这一问题可以避免,见第三种方法)




    <三>、使用placement new
        方法是:先为此数组分配raw memory,然后使用"placement new"在这块内存上构造EquipmentPiece objects;


        //分配足够的raw memory,给一个预备容纳10个EquipmentPiece objects的数组使用
        void *rawMemory = operator new(10*sizeof(EquipmentPiece));


        //让bestPieces指向此内存,使这块内存被视为一个EquipmentPiece数组
        EquipmentPiece *bestPieces = reinterpret_cast<EquipmentPiece*>(rawMemory);


        //利用"placement new"构造这块内存中的EquipmentPiece objects。
        int IDNumber = 0;
        for(int i = 0; i < 10; i++){
            new (&bestPieces[i]) EquipmentPiece( IDNumber );
        }


    注意:该方法维护比较困难。在数组内对象结束生命时,要以手动方式调用destructors,最后还得调用operator delete释放raw memory。
        //将bestPieces中对象以构造次序的反序析构掉
        for(i = 0; i < 10; i++){
            bestPieces[i].~EquipmentPiece();
        }


        //释放raw memory
        operator delete (rawMemory);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类对象数组初始化(三种方法) 的相关文章

  • EF Core 返回 null 关系,直到直接访问

    我有一些如下所示的模型 public class Mutant public long Id get set Relations public long OriginalCodeId get set public virtual Origi
  • 错误:表达式不可赋值三元运算符

    我有以下代码 MPLABX XC8 编译器给出此错误 错误 表达式不可分配 U1ERRIRbits RXFOIF uart1 oerr 1 uart1 oerr 0 这是相关代码部分 typedef union struct bool fe
  • 带有 ASP.NET 按钮回发的 jQuery UI 对话框

    我的 ASP NET 页面上有一个运行良好的 jQuery UI 对话框 jQuery function jQuery dialog dialog draggable true resizable true show Transfer hi
  • 非模板函数中的尾随返回类型[重复]

    这个问题在这里已经有答案了 我见过有人使用以下语法来实现函数 auto get next gt int 代替 int get next 我理解两者 并且我知道尾随返回类型语法对于使用 decltype 的模板代码很有用 就我个人而言 我会避
  • 并行运行多个任务

    我有一个代理列表 每个代理都会访问不同的站点并从站点中提取所需的数据 目前它一次只做一个 但我希望同时运行 10 20 个任务 这样它就可以一次性从 20 个站点下载 而不是只下载一个 这是我目前正在做的事情 private async T
  • 使用 POST 的 HttpWebRequest 的性能

    我有一个用于测试网络服务的小工具 它可以使用 POST 或 GET 调用 Web 服务 使用POST的代码是 public void PerformRequest WebRequest webRequest WebRequest Creat
  • 来自 double 的 static_cast 可以优化分配给 double 吗?

    我偶然发现了一个我认为不必要的功能 并且通常让我感到害怕 float coerceToFloat double x volatile float y static cast
  • C++中类成员函数相互调用有什么好处?

    我是 C 新手 我发现下面的编程风格对我来说很有趣 我在这里写了一个简化版本 include
  • Visual Studio 2013 调试器显示 std::string 的奇怪值

    我有一个大型的 cmake 生成的解决方案 其中包含许多项目 由于某种原因 我无法查看字符串的内容 因为根据调试器 Bx Buf含有一些垃圾 text c str 正确返回 Hello 该问题不仅仅发生在本地字符串上 返回的函数std st
  • 注入包含接口的所有已注册实现的 Enumerable

    给出以下接口 public interface IMyProcessor void Process 我希望能够注册多个实现 并让我的 DI 容器将它们的可枚举注入到这样的类中 public class MyProcessorLibrary
  • 如何从 Powerpoint 2010 导出电影?

    如何使用 MS Office PIA 主互操作程序集 或其他方式以编程方式将嵌入视频从 powerpoint 2010 导出到外部文件 在演示文稿中嵌入视频是 Powerpoint 2010 中的一项新功能 我找不到解决方案 PPTX 文件
  • C# 可以为控制台应用程序部分类“程序”类吗?

    我想知道是否可以将为任何控制台应用程序创建的默认 程序 类更改为部分类 我想这样做是因为我想要更好的组织 而不是将所有方法都放在按区域分类的 1 个文件中 对我来说 将某些方法类别放在单独的文件中会更有意义 我对分部类的理解是 它是多个文件
  • MINIX内部碎片2

    我正在用 C 语言编写一些软件 它递归地列出给定目录中的所有文件 现在我需要计算出内部碎片 我花了很长时间研究这个问题 发现 ext2 上的内部碎片只发生在最后一个块中 我知道理论上你应该能够从索引节点号获得第一个和最后一个块地址 但我不知
  • 使用未命名命名空间而不是静态命名空间

    我可以假设在未命名命名空间中声明的对象相当于static namespace int x 1 static int x 2 FWIK 在这两种情况下 x将具有静态存储期限和内部链接 声明为的对象的所有规则也是如此static适用于未命名名称
  • 让 Windows 尝试读取文件

    我正在对 Windows 文件系统进行某种封装 当用户请求打开文件时 Windows 调用我的驱动程序来提供数据 在正常操作中 驱动程序返回缓存的文件内容 但是 在某些情况下 实际文件没有缓存 我需要从网络下载它 问题是是否有可能让 Win
  • c++ - <未解析的重载函数类型>

    在我的班级里叫Mat 我想要一个将另一个函数作为参数的函数 现在我有下面 4 个函数 但是在调用 print 时出现错误 第二行给了我一个错误 但我不明白为什么 因为第一行有效 唯一的区别是功能f不是班级成员Mat but f2是 失败的是
  • 为什么存在系统调用

    我一直在阅读有关系统调用及其在 Linux 中如何工作的内容 我还有更多的阅读要做 但我读过的一件事都没有回答 那就是 为什么我们需要系统调用 我知道系统调用是用户空间程序要求内核执行某些操作的请求 但我的问题基本上是 为什么用户空间程序本
  • 跟踪白色背景中的白球(Python/OpenCV)

    我在 Python 3 中使用 OpenCV 来检测白场上的白 黑球 并给出它的精确 x y 半径 和颜色 我使用函数 cv2 Canny 和 cv2 findContours 来找到它 但问题是 cv2 Canny 并不总是检测到圆的完整
  • 使用通用存储库模式和流畅的 nHibernate

    我目前正在开发一个中型应用程序 它将访问不同站点上的 2 个或更多 SQL 数据库等 我正在考虑使用类似的东西 http mikehadlow blogspot com 2008 03 using irepository pattern w
  • 将同步 zip 操作转换为异步

    我们有一个现有的库 其中一些方法需要转换为异步方法 但是我不确定如何使用以下方法执行此操作 错误处理已被删除 该方法的目的是压缩文件并将其保存到磁盘 请注意 zip 类不公开任何异步方法 public static bool ZipAndS

随机推荐