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

2023-12-07

[ 这是后续memcpy() 可以用来更改“const”成员数据吗?. And 声明 C++ 不可变类的惯用方式真正解决这个问题,尤其是this回答“在围绕不可变数据设计的语言中,它知道它可以“移动”您的数据,尽管它具有(逻辑)不变性。” ]


Given a struct with const members

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 see:

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

Both point2d and Bar完全按照预期工作;是的,point2d是完全不可变的。

但是,我真的想要一个不同的实现Bar存储的point2d实例作为成员数据。有什么办法可以实现这一点吗?使用放置new据说结果是未定义的行为(见评论)。

#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 };
    }
};

Does not using 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? Or is Baz还可以吗?或者两者都不是,唯一的解决方案是Bar?


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

使用对象在其生命周期结束后,如所提供的示例代码我写这个答案时做了 in

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 };
}

这可能感觉像是不必要的复杂化和可能的微观低效率,但更确切地说,不必要的复杂化是点类。

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

可以使用“new”位置来更改“const”数据吗? 的相关文章

  • C# 打印问题(RichTextBox)

    我想打印我的 RichTextBox eintragRichTextBox 的内容 我现在有这个代码 private void druckenPictureBox Click object sender EventArgs e PrintD
  • 在 C# 中调用 C++ 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有很多用 C 编写的库 我想从 C 调用这些库 但是 我遇到了很多问题 我想知道是否有书籍或指南告诉我如何做到这一点 Dll导入 htt
  • std::call_once 可重入且线程安全吗?

    std call once http en cppreference com w cpp thread call once是线程安全的 但它也是可重入的吗 我使用 VS2012 调试和发布 进行的测试表明 调用std call once从单
  • 是否存在指向不同类型的指针具有不同大小的平台?

    C 标准允许指向不同类型的指针具有不同的大小 例如sizeof char sizeof int 是允许的 但是 它确实要求如果将指针转换为void 然后转换回其原始类型 它必须与其原始值进行比较 因此 从逻辑上来说 sizeof void
  • 在开关中使用“goto”?

    我看到了一个建议的编码标准 内容如下Never use goto unless in a switch statement fall through 我不跟 这个 例外 案例到底是什么样的 这证明了goto 此构造在 C 中是非法的 swi
  • Gwan C#,如何获取HTTP标头?

    我需要它来重写 url 以了解我正在处理哪个友好的 url 用于用户代理和其他东西 EDIT public class Gwan MethodImplAttribute MethodImplOptions InternalCall exte
  • 为什么'enable_if'不能用于禁用这里声明

    include
  • 一元 +/- 运算符如何可能导致“-a”或“+a”中的整数提升,“a”是算术数据类型常量/变量?

    这句看似微不足道的台词摘自我的迈克 巴纳汉和布雷迪的 C 书 第 2 8 8 2 节 http publications gbdirect co uk c book chapter2 expressions and arithmetic h
  • 使用 LINQ 更新 IEnumerable 对象的简单方法

    假设我有一个这样的业务对象 class Employee public string name public int id public string desgination public int grade List
  • 访问 ascx 文件中的母版页控件

    我有一个母版页文件 其中包含 2 个面板控件中的 2 个菜单 我还使用控件来检查用户是否登录并获取用户类型 根据我想要显示 隐藏面板的类型 控件本身不在母版页中引用 而是通过 CMS 系统动态引用 我想在用户控件中使用findcontrol
  • 使用查询表达式对 List 进行排序

    我在使用 Linq 订购这样的结构时遇到问题 public class Person public int ID get set public List
  • 使用具有抗锯齿功能的 C# 更改抗锯齿图像的背景颜色

    我有一个图像需要更改背景颜色 例如 将下面示例图像的背景更改为蓝色 然而 图像是抗锯齿的 所以我不能简单地用不同的颜色替换背景颜色 我尝试过的一种方法是创建第二个图像 仅作为背景 并更改其颜色并将两个图像合并为一个图像 但是这不起作用 因为
  • Project Euler #8,我不明白我哪里出了问题[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在做项目欧拉第八题 https projecteuler net problem 8 其中我得到了这个大得离谱的数字 7316
  • 使用 GCC 生成可读的程序集?

    我想知道如何使用GCC http en wikipedia org wiki GNU Compiler Collection在我的 C 源文件中转储机器代码的助记符版本 这样我就可以看到我的代码被编译成什么 你可以使用 Java 来做到这一
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • 选择查询不适用于使用Parameters.AddWithValue 的参数

    C 中的以下查询不起作用 但我看不出问题所在 string Getquery select from user tbl where emp id emp id and birthdate birthdate cmdR Parameters
  • 使用 jQuery 从 ASP.Net JSON 服务获取数据

    我正在尝试调用 Google 地图地理编码 API 从纬度 经度对中获取格式化的地址 然后将其记录到控制台 我正在尝试获取为给定位置返回的第一个 formatted address 项目 我很简单无法从 JSON 中提取该项目 我不知道为什
  • CUDA 8 编译错误 -std=gnu++11

    我正在尝试转换一些代码以使用 CUDA 并且我认为我遇到了兼容性问题 我们使用CMake 这些是我使用的 gcc 和 CUDA 版本 gcc version gcc Ubuntu 5 4 0 6ubuntu1 16 04 5 5 4 0 2
  • DataContractSerializer 事件/委托字段问题

    在我的 WPF 应用程序中 我正在使用DataContractSerializer序列化对象 我发现它无法序列化具有事件或委托声明的类型 考虑以下失败的代码 Serializable public abstract class BaseCl
  • 如何将 SQL“LIKE”与 LINQ to Entities 结合使用?

    我有一个文本框 允许用户指定搜索字符串 包括通配符 例如 Joh Johnson mit ack on 在使用 LINQ to Entities 之前 我有一个存储过程 该存储过程将该字符串作为参数并执行以下操作 SELECT FROM T

随机推荐

  • 在网页上加载 javascript 时输入意外结束

    我的 输入意外结束 的情况与我迄今为止在 SO 和其他论坛中发现的所有情况有所不同 坦白说 我被困住了 我在 CentOS 机器上安装了 JBoss EAP 6 4 尝试在 Windows 7 机器上打开管理控制台 MS 的所有最新补丁 都
  • 为什么 emplace_back() 会有这样的行为?

    为什么 Base 在调用 emplace back 之后立即被调用 为什么在析构函数调用后可以访问 sayHello 为什么 Base 再次被调用 include
  • IE11 Selenium WebDriverException:无法导航。 (org.openqa.selenium.WebDriverException ...IWebBrowser2::Navigate2() 失败

    我是自动化测试新手 虽然我的 Selenium 测试在 Chrome 和 Firefox 上运行 但它们没有在 IE11 上运行 我做了下面详细说明的所有检查 但我不断遇到此错误 org openqa selenium WebDriverE
  • 如何一次只打开 1 个手风琴

    accordion on click accordion control function e e preventDefault this next accordion panel not animated slideToggle ul c
  • 将 SMB 添加到 Windows,这有多安全?

    我遇到了一个小黑客 它声称它可以在 Windows 上启用 smb 抱怨是这样的事情 a href text a 没工作 虽然您确实可以在 url 中使用 file 但用户希望使用 smb 以便它是跨平台的 黑客攻击的过程如下 1 创建这个
  • MySQL IFNULL“N/A”产生“在集合中找不到项目”错误

    我一直在使用 ISNULL 函数在 mySQL 查询中将 NULL 值转换为零 如下所示 SELECT IFNULL mem comment count 0 FROM members 这很好用 我现在尝试使用 IFNULL 函数将 NULL
  • 使用 Python gtk3 在 X 上进行全局键绑定

    我正在寻找一些可以与 gtk3 一起使用的 python xlib 全局键绑定示例 就像为 gtk2 所做的那样http www siafoo net snippet 239 这里的代码非常相似 from Xlib display impo
  • 如何添加NodeJs、S3、heroku直接上传到android?

    我试图了解如何将他们提供示例的方式从网站转换为 android retrofit 这是该网站的代码示例 function get signed request file var xhr new XMLHttpRequest xhr open
  • 多个子进程在同一管道上读/写

    我目前正在Linux环境中使用C语言学习套接字编程 作为一个项目 我试图编写一个基本的聊天服务器和客户端 目的是让服务器为每个连接的客户端分叉一个进程 我遇到的问题是读取一个孩子的数据并将其写入所有连接的客户端 我尝试通过在子级中循环调用
  • 是否可以在 ES6 Set 实例上使用数组迭代方法?

    我正在使用 ES6 Set 实例 我需要对它们应用一些转换 如果它们是数组的话 这些转换就会很简单 这是一个例子 let s new Set s add 1 s add 2 s add 3 let n s filter val gt val
  • 求和常量时的隐式缩小与求和变量时的显式缩小

    我写了一个程序 class First public static void main String args int c 5 byte b c 6 System out println b 我的 javac 输出是 error incom
  • 将一行转置为多行 Oracle

    我有一个总是返回一行的查询many列 我想把它变成 2 列和许多行 原始结果 Col1 Col2 Col3 Col4 val1 val2 val3 val4 我想要的是 ColName Value Col1 val1 Col2 val2 C
  • 了解 Chrome 网络日志“停滞”状态

    我在 Chrome 中有以下网络登录 我不明白其中的一件事 填充的灰色条和透明的灰色条有什么区别 谷歌对这些字段进行了细分评估网络性能他们的 DevTools 文档的部分 摘自资源网络时序 停滞 阻塞 请求在发送之前等待所花费的时间 该时间
  • 为什么不调用成员变量的移动构造函数?

    考虑以下课程 如果我自己实现移动构造函数如下 为什么是 bar 成员b不是移动而是复制 但如果我使用默认的移动构造函数 那么b被感动了 为什么b rhs b 不打电话bar bar 我使用 g 9 2 1 和 std c 11 class
  • jQuery滚动显示隐藏内容

    如何使默认情况下页面上显示 6 个 div 元素 并且当用户滚动到页面底部时 再加载 6 个元素 如果你看到这个example 它有多个div 我希望最初只显示其中 6 个 每次用户到达页面底部时 我希望再加载 6 个 直到您 用完 div
  • 使用什么语法从 JavaDB 数据库中选择常量字段值?

    我在用着UNION ALL结合几个结果SELECT查询成一ResultSet 我使用常量字段值来标识哪条语句生成了每一行 这适用于 MySQL 但 Java DB 会抛出异常SQLSyntaxErrorException 指向第一个常量字段
  • Mac OSx 10.8 上 IDLE (Python 3.3.2) 中的 NumPy

    我知道这可能是一个重复的问题 但我在这里找到的所有答案都超出了我的想象 我对 Python 很陌生 但我想在 IDLE 中使用 NumPy python 3 3 2 IDLE 似乎无法访问 OSX 10 8 即 python 2 7 附带的
  • 按关键字对数组中的元素进行分组

    我正在 AngularJS 1 上开发一个应用程序 但我不知道如何按项目拆分另一个数组中的项目数组 我的意思是我有一系列不同的项目 我会按 uuid 对项目进行分组 如下所示 name toto uuid 1111 name tata uu
  • 做 {...} while(false)

    我正在查看一个人的一些代码 注意到他的函数中似乎有一个模式
  • 可以使用“new”位置来更改“const”数据吗?

    这是后续memcpy 可以用来更改 const 成员数据吗 And 声明 C 不可变类的惯用方式真正解决这个问题 尤其是this回答 在围绕不可变数据设计的语言中 它知道它可以 移动 您的数据 尽管它具有 逻辑 不变性 Given a st