ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c-可以使用位置“ new”来更改“ const”数据吗?

2019-10-09 10:21:08  阅读:256  来源: 互联网

标签:placement-new c const immutability


[这是can memcpy() be used to change “const” member data?的后续措施.Idiomatic Way to declare C++ Immutable Classes确实引起了问题,尤其是this回答“在围绕不可变数据设计的语言中,它知道(尽管)(逻辑)不可变也可以“移动”数据”. ]

给定具有const成员的结构

struct point2d { const int x; const int y; }; // can't change to remove "const"

持有指向point2d的指针的类可以指向具有不同值的新point2d实例.

struct Bar
{
    std::unique_ptr<point2d> pPt_{ new point2d{ 0, 0 } };
    const point2d& pt() const {
        return *pPt_;
    }

    void move_x(int value) {
        pPt_.reset(new point2d{ pt().x + value, pt().y });
    }
};

酒吧的客户看到:

   Bar bar; // (0, 0)
   bar.move_x(3141); // (3141, 0)

point2d和Bar都完全按照要求工作.是的,point2d是完全不变的.

但是,我真的很喜欢Bar的另一种实现,该实现将point2d实例存储为成员数据.有什么办法可以做到这一点?使用新的放置可能会导致undefined behavior(请参阅注释).

#include <new>
struct Baz
{
    point2d pt{ 0, 0 };

    void move_x(int value) {
        // ** is this undefined behavior ? **
        new (&pt) point2d { pt.x + value, pt.y };
    }
};

不能直接使用point2d作为成员数据来解决(潜在的?)未定义行为吗?

struct Blarf
{
    unsigned char pt_[sizeof(point2d)];
    const point2d& pt() const {
        return *reinterpret_cast<const point2d*>(pt_);
    }

    Blarf() {
        new (&pt_) point2d{ 0, 0 };
    }

    void move_x(int value) {
        new (&pt_) point2d{ pt().x + value, pt().y };
    }
};

哪个是对的?只是布拉夫?还是巴兹还行吗?还是都不是,唯一的解决方案是Bar?

解决方法:

您可以在对象的生命周期结束后重新使用存储.生存期以析构函数调用结束.在技​​术上没有任何问题.

在对象的生命周期结束后使用该对象,就像在我编写此答案时所提供的示例代码所做的那样

pt.~point2d();
new (&pt) point2d { pt.x + value, pt.y };

是未定义的行为.

如果您坚持将点类与const字段一起使用,则可以这样解决:

void move_x( int const value )
{
     auto const old_pt = pt;
     pt.~point2d();
     ::new (&pt) point2d { old_pt.x + value, old_pt.y };
}

这可能感觉像是不必要的复杂性和可能的​​微观效率低下,但是,不必要的复杂性就是要点类.

标签:placement-new,c,const,immutability
来源: https://codeday.me/bug/20191009/1878367.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有