[이것은 can memcpy() be used to change “const” member data?의 후속 조치입니다. 그리고 Idiomatic Way to declare C++ Immutable Classes은 실제로 문제가 발생합니다. 특히 this 대답은 "불변의 데이터를 중심으로 한 언어에서, 그것은 (논리적 인) 불변성에도 불구하고 데이터를"이동할 "수 있다는 것을 알게 될 것입니다. ]"const"데이터를 바꾸기 위해 "new"배치를 사용할 수 있습니까?
는 struct
const
와 회원
struct point2d { const int x; const int y; }; // can't change to remove "const"
다른 값을 갖는 새 point2d
인스턴스를 가리킬 수 있습니다 point2d
에 대한 포인터를 보유하는 클래스 감안할. Bar
의
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
은 완전히 변경할 수 없습니다.
그러나 실제로는 회원 데이터로 point2d
인스턴스를 저장하는 Bar
의 다른 구현이 필요합니다. 이것을 달성 할 수있는 방법이 있습니까? 게재 위치 new
을 사용하면 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 };
}
};
어느 쪽이 맞습니까? 그냥 Blarf
? 또는 Baz
도 OK! 아니면 둘 다, 유일한 해결책은 Bar
입니까?
왜 귀하가 링크 된 "증거"가 새로운 게재 위치와 관련이 없으면 배치 결과가 UB가되는 이유는 무엇입니까? 내가 뭘 놓치고 있니? –
@Lightness 링크 된 답변의 주석은 배치가 'new'는'memcpy()'와 같습니다. –
오, 주석. 나는 Sam와 동의 할 것이다. 새로운 as-if는 원본을 파괴하고 ('int'와 같이 사소하게 파괴 가능하면 잘 정의되어 있습니다.) 새로운 것을 대체합니다. "개체"는 메모리에있는 영역입니다.그러나 유형도 있습니다. 두 사람은 새로운 배치를 할 확률이 높습니다. UB인지 여부에 관한 질문은 매우 흥미로울 것입니다. 그 질문을 먼저 물어볼 것입니다. –