【问题标题】:How does a C++ constructor initialize objects of its class?C++ 构造函数如何初始化其类的对象?
【发布时间】:2019-12-06 13:57:45
【问题描述】:

我从C++之旅中读到了这篇文章,

"与普通函数不同,保证使用构造函数 初始化其类的对象。因此,定义构造函数消除了类未初始化变量的问题。”

这个初始化是如何工作的?例如,假设我有一个类,其字段“s”的类型为string

class C{   
     std::string s;   
     ...

}

“s”是如何初始化的,无论编译器如何保证它的值都是空字符串?

【问题讨论】:

标签: c++ constructor


【解决方案1】:

这段话的意思是,如果你有一个Initialise() 函数,有人可能会忘记调用它。它不是“保证被使用”,因为你无法控制人。另一方面,你不能“忘记”调用构造函数,因为你从不调用构造函数:当你实例化你的对象时,计算机会为你做这件事。

当然,这并不意味着构造函数可以被正确编写;这仍然取决于你。但是,对于像 std::string 这样的类,很难弄错,因为如果您不编写代码来做其他事情,它至少是默认构造的。

无论您是否有一个应该稍后调用的 Initialise() 函数都会发生这种情况,但是如果您确实在构造函数中进行了一些更复杂的初始化,那么您可以放心,这段代码将运行。

// Bad! People can forget to call Initialise, so the string might stay empty
class Foo
{
public:
    void Initialise(const bool yesOrNo)
    {
        m_string = (yesOrNo ? "Yes!" : "No");
    }

private:
    std::string m_string;
};

// Good! You'll always have a value; no way around that
class Bar
{
public:
    Bar(const bool yesOrNo)
       : m_string(yesOrNo ? "Yes!" : "No")
    {}

private:
    std::string m_string;
};

进一步阅读:

【讨论】:

  • @user253751 但实际上,这分配了一个可用的对象,除了构造函数没有被调用 不,它没有。在 C++ 中创建对象的唯一方法是在隐式更改联合的活动成员或创建临时对象时通过 new 表达式进行定义。 reference
  • @user253751 好吧,你说的是:未定义的行为。我承认我的回答是基于你正确声明你的对象的想法,并且仍然有办法欺骗系统,但无论如何我相信这是教科书试图达到的。至于“实际上,这分配了一个可用的对象,除了构造函数没有被调用”,这是你真正需要摆脱的信念。 :)
  • @user253751 我相信你它会编译,甚至看起来可以工作。但是,您对“可用”的定义充其量是乐观的。如果您的项目中有此代码,您应该修复它,否则您有一个隐藏的错误。永远不要低估编译器假设您的程序没有 UB 的驱动力。你从来没有创建过一个对象,所以你有各种奇怪的风险。记住,你不是在给电脑编程;您正在抽象地描述一个程序,并且您必须遵循为此制定的规则,除非您想要痛苦。
  • @user253751 通过观察预期行为来推理未定义的行为是无稽之谈。甚至 "this allocates an object" 也不正确。没有分配对象,只分配原始内存。
  • @user253751 我希望您不要在安全关键的环境中工作。任何形式的 UB 都是不好的做法,即使编译器做了理智的事情。不确定你的情况,但有保证的行为是我一直努力的目标。
【解决方案2】:

当您的C 实例被创建时,std::string s 被初始化为Member initialization

“s”是如何初始化的,它的值是否可以保证 空字符串是什么编译器?

你没有向我们展示你是如何创建C的,所以我们不知道使用了什么构造函数。如果使用默认构造函数,则std::string 的默认构造函数用于s。正如here 解释的那样,这确实是一个空字符串:

默认构造函数。构造空字符串(零大小和 未指定的容量)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-05
    • 2021-11-06
    • 2015-08-28
    • 2013-12-30
    • 1970-01-01
    • 2021-07-26
    • 2013-05-23
    • 1970-01-01
    相关资源
    最近更新 更多