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

时间:2016-07-08 12:41:34

标签: c++ member assignment-operator

对于Comparator comparator = Collections.reverseOrder(); Collections.sort(YourarrayList,comparator); System.out.println("After sorting ArrayList in descending order"+YourarrayList); 成员struct

const

用作会员数据

struct point { const int x; const int y; };

如何编写struct Foo { point pt{ 0, 0 }; void move_x(int value); }; 来更新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_;
}

#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 }); } }; 始终存储在堆上而不是point中。

请注意,客户根本不关心Bar

point

2 个答案:

答案 0 :(得分:9)

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

有人写一些代码为pt,调用move_x(),然后再次阅读pt,这只是时间问题。

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

然后,倒霉的程序员将花费一周的时间来弄清楚为什么代码显然没有按照程序所说的那样做。

答案 1 :(得分:0)

尝试将memcpyconst成员一起使用时,您将收到编译错误,如下所示:

#include <cstdlib>
#include <cstdio>
#include <cstring>

struct foo
{
    public:
        foo(int init_x);
        const int x;
        int bar();
};

foo::foo(int init_x): x(init_x) {}

int foo::bar()
{
    int *y = (int *) malloc(sizeof(int));
    *y = 6;
    memcpy(&x, y, sizeof(int));
    return x;
}

int main(int argc, char *argv[])
{
    foo f{5};
    printf("%d\n", f.bar());
}

以上结果

error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
    memcpy(&x, y, sizeof(int));

虽然我在这个例子中使用了const int,但如果你改为使用const int指针成员,你会发现相同的结果,即

const int *x;

但是,如果删除const描述符并使用:

int x;

(或int *x;,就此问题而言)错误不再发生,程序会打印6,正如人们所料。

所以这就引出了一个问题,如果你知道某些事情会被宣布为const

  • 如果您有能力更改声明,则无法自行删除const吗?
  • 如果您无法更改声明,您是否有理由打破const所做的“承诺”?