C++ 中初始化对象的不同方式

2024-03-01

想象一下这个类:

class Entity {
public:
    int x, y;
    
    Entity() : x(0), y(0) { }
    Entity(int x, int y) : x(x), y(y) { }
}

以下是我认为我所知道的初始化类的多种方法:

Entity ent1;                //Uses the default constructor, so x=0 and y=0
Entity ent2();              //Uses the default constructor, so x=0 and y=0 (Not sure)
Entity ent3(1, 2);          //Made constructor, so x=1 and y=2
Entity ent4 = Entity();     //Default constructor, so x=0 and y=0
Entity ent5 = Entity(2, 3); //Made constructor, so x=2 and y=3

我知道可以在堆内存上创建一个对象,但这不是我目前正在寻找的。

我的问题是,这些初始化对象的方式有什么区别?

我不确定何时应该使用哪一个。


初始化的区别不仅在于其形式,还在于 正在初始化的实体类型。在本例中,它是一个类类型对象,具有已定义的默认构造函数以及带参数的构造函数。

Entity ent1;  

上面的语句是默认初始化,这会导致调用该类的默认构造函数Entity.


Entity ent2();

如果可能的话,上面的声明将被编译器视为函数原型。Entity将返回函数的类型ent2,不带任何参数。这被称为一个案例最麻烦的解析(MVP)及其存在导致了误导性的“聪明的愚蠢规则”的出现:“永远不要使用括号”。


在这样的语句中,将调用与参数列表匹配的用户定义的构造函数ent3 object:

Entity ent3(1, 2);    // calls Entity(int x, int y)

MVP 可以罢工的另一种情况是这样的:

Entity ent3_1(int(a), int(b));  // It's not what it looks like.

ent3_1上面不是变量。该语句声明了一个带有两个 int 参数的函数。int(a)int a是 C 语言和声明语法的遗产,它忽略了“额外”括号。


Entity ent4 = Entity();

ent4 is a proper的版本ent2C++11 之前的情况。默认构造函数作为值初始化的一部分被调用。它的形式可以避免歧义解决原则,这使得ent2 and ent3_1不正确。这里的等号不是赋值,因为没有operator=呼叫将发生在这里。它是声明语法的一部分,用于标记初始化表达式。


Entity ent5 = Entity(2, 3);

ent5是ent3案例的一个版本。作为值初始化的一部分调用的用户定义的构造函数。


你的问题被标记为C++11,C++11允许统一的初始化语法:

Entity ent12{};     // This is a legal alternative of ent2 case
Entity ent13{1, 2}; // A call to constructor or member initialization
Entity ent13{ int(a), int(b) }; // Not a function anymore
Entity ent14 = {};              // Not an assignment
Entity ent15 = Entity{2, 3};    // Not an assignment either!

请注意,统一初始化语法有一个警告。例如。这条线

std::vector<int> v(10); 

声明一个包含 10 个元素的向量。但这个

std::vector<int> v{10};

声明一个用值为 10 的 int 类型的单个元素初始化的向量。发生这种情况是因为std::vector有一个定义了以下签名的构造函数:

vector( std::initializer_list<T> init, const Allocator& alloc = Allocator() );

如果您既不能使用 () 而不触发 MVP,也不能使用 {} 而不调用不需要的构造函数,则可以使用值初始化赋值语法来解决该问题。

附录:必看

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

C++ 中初始化对象的不同方式 的相关文章

  • 将 new 与 decltype 一起使用

    T t T is an implementation detail t new T want to avoid naming T to allow for flexibility t new decltype t error cannot
  • 单元测试验证失败

    我正在运行我的单元测试PostMyModel路线 然而 在PostMyModel 我用的是线Validate
  • 检测wlan是否关闭

    任何人都可以给我一个提示 如何在 Windows Phone 上以编程方式检测 C 8 1 应用程序 不是 8 0 是否启用 禁用 WLAN 我不想更改这些设置 只是需要知道 该解决方案是一个 Windows 8 1 通用应用程序 Wind
  • 在现代 C++ 中,临时生命周期延长何时有用?

    在 C 中 您可以将函数的返回值 返回值 而不是引用 绑定到 const 引用 并且代码仍然有效 因为该临时对象的生命周期将延长到作用域末尾 例如 std string get string return abc void f const
  • CSharpRepl emacs 集成?

    我碰巧知道莫诺CSharpRepl http www mono project com CsharpRepl 是否有 emacs csharp 模式使用它在一个窗口中运行 REPL 并像 python 模式一样在另一个窗口中编译 运行 C
  • 从代码中,如何创建对存储在附加属性中的对象的属性的绑定?

    我们有一个继承的附加属性来存储一个对象 在可视化树的更下方 我们希望从代码绑定到该对象的属性 通常我们像这样构建绑定的路径部分 var someBinding new Binding Path new PropertyPath Attach
  • 如何使用 SOAP 且不使用 WSE 在 .NET 中签署 Amazon Web 服务请求

    亚马逊产品广告 API 以前称为 Amazon Associates Web Service 或 Amazon AWS 实施了一项新规则 即自 2009 年 8 月 15 日起 向其发送的所有 Web 服务请求都必须经过签名 他们在其网站上
  • 从模板切换传递的类型

    在 C 中是否可以检查传递给模板函数的类型 例如 template
  • 检测到堆栈崩溃

    我正在执行我的 a out 文件 执行后 程序运行一段时间 然后退出并显示消息 stack smashing detected a out terminated Backtrace lib tls i686 cmov libc so 6 f
  • C# 开源 NMEA 解析器 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找 C 开源 NMEA 解析器 嗯 我自己也不熟悉 但是一些快速搜索显示了一个代码项目 htt
  • 使用 LINQ 更新 IEnumerable 对象的简单方法

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

    我有一个母版页文件 其中包含 2 个面板控件中的 2 个菜单 我还使用控件来检查用户是否登录并获取用户类型 根据我想要显示 隐藏面板的类型 控件本身不在母版页中引用 而是通过 CMS 系统动态引用 我想在用户控件中使用findcontrol
  • C# 编译器不会优化不必要的强制转换

    前几天 在写答案的时候这个问题 https stackoverflow com questions 2208315 why is any slower than contains在这里 关于溢出 我对 C 编译器感到有点惊讶 它没有按照我的
  • UI 函数在快速事件完成之前触发

    我有一个停靠在 Silverlight 应用程序中的 Web 浏览器框架 有时会在其上弹出全窗口 XAML Silverlight UI 元素 我已经或多或少修复了一个老问题 即 Web 框架的内容似乎与 Silverlight 内容不能很
  • 使用 C# 和 wpf 创建类似 Dock 的应用程序

    我需要创建一个与我们购买笔记本电脑时获得的应用程序类似的应用程序 仅当鼠标指针到达窗口顶部时它才可见 那么我怎样才能使用 C 4 0 来做到这一点呢 http www notebookcheck net uploads pics win2
  • 搜索实体的所有字段

    我正在尝试在客户数据库上实现 多功能框 类型的搜索 其中单个查询应尝试匹配客户的任何属性 这是一些示例数据来说明我想要实现的目标 FirstName LastName PhoneNumber ZipCode Mary Jane 12345
  • 为什么 Cdecl 调用在“标准”P/Invoke 约定中经常不匹配?

    我正在开发一个相当大的代码库 其中 C 功能是从 C P Invoked 的 我们的代码库中有很多调用 例如 C extern C int stdcall InvokedFunction int 使用相应的 C DllImport CPlu
  • 使用 GCC 生成可读的程序集?

    我想知道如何使用GCC http en wikipedia org wiki GNU Compiler Collection在我的 C 源文件中转储机器代码的助记符版本 这样我就可以看到我的代码被编译成什么 你可以使用 Java 来做到这一
  • C++ 中 void(*)() 和 void(&)() 之间的区别[重复]

    这个问题在这里已经有答案了 在此示例代码中 func1是类型void int double and funky是类型void int double include
  • 使用 using 声明时,非限定名称查找如何工作?

    根据 C 标准 这是格式错误还是格式良好 namespace M struct i namespace N static int i 1 using M i using N i int main sizeof i Clang 拒绝它 GCC

随机推荐