可以用memcpy()来改变"const"成员数据吗?

Ðаn*_*Ðаn 4 c++ member assignment-operator

对于structconst会员

struct point { const int x; const int y; };
Run Code Online (Sandbox Code Playgroud)

用作会员数据

struct Foo
{
    point pt{ 0, 0 };
    void move_x(int value);
};
Run Code Online (Sandbox Code Playgroud)

如何Foo::move_x()写更新Foo::pt?可以使用memcpy()吗?

#include <memory.h>
void Foo::move_x(int value)
{
    const point pt_{ pt.x + value, pt.y };
    (void) memcpy(&pt, &pt_, sizeof(pt_)); // pt = pt_;
}
Run Code Online (Sandbox Code Playgroud)

这可以使用指针安全地完成

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

    void move_x(int value) {
        pPt_.reset(new point{ pt().x + value, pt().y });
    }
};
Run Code Online (Sandbox Code Playgroud)

但是point它总是存储在堆上而不是存储在堆中Bar.

请注意,客户根本不关心point:

   Foo foo;
   foo.move_x(314); // (314, 0)

   Bar bar;
   bar.move_x(3141); // (3141, 0)
Run Code Online (Sandbox Code Playgroud)

Sam*_*hik 9

这显然是未定义的行为.现在,"可以"这样做吗?当然,它可以,但只是在编译器不会抱怨的意义上.但是C++的一个方面就是因为编译器没有抱怨它并不意味着生成的代码能够正常工作.

有人写一些读取pt,调用move_x()然后再读取的代码只是时间问题pt.

一个现代的优化编译器将正确地假设因为代码正在读取const实例,它们的值不能改变,然后pt使用ptCPU寄存器中第一次读取时缓存的数据继续并优化第二次读取.

然后,倒霉的程序员将花费一周时间试图弄清楚为什么代码显然不会执行程序所说的应该做的事情.

  • @Dan为什么你坚持尝试改变不可变数据?如果内部代码需要修改外部代码无法修改的数据,那么您需要的是封装,而不是某些语言破解 (2认同)