构造函数中的堆栈分配中间对象

Stack allocating intermediate objects in contructors

当构造函数分配需要传递给其他生命周期更长的构造函数的中间对象时,中间对象可以堆栈分配吗?

例如,我有一个 class Reader,它在 std::wistream 之上构建了各种实用程序,std::wistream 具有针对各种用例的多个构造函数:

Reader唯一的相关会员数据是:

std::unique_ptr<std::wistream> m_character_stream

Note: wistream, not istream. The constructors construct the wistream in various ways depending on their argument types.

例如,第一个构造函数形式,如下所示:

Reader::Reader(std::unique_ptr<std::istream> bytestream) {
    auto conversion = std::wbuffer_convert<std::codecvt_utf8<wchar_t>, wchar_t, std::char_traits<wchar_t>>(bytestream->rdbuf());

    m_character_stream = std::make_unique<std::wistream>(&conversion);
}

我的问题是:

  1. 我想因为我被传递了一个 unique_ptr,所以我别无选择,只能将它 std::move 给一些其他无用的成员变量以使其保持活动状态,直到我们被破坏了吗?即使我的 class 的其余部分永远不会直接使用该变量,而只会通过 m_character_stream?

    间接使用
  2. conversion 对象是堆栈分配的。那会有问题吗?我假设当构造函数returns时,这个对象将被删除。这会导致 std::wistream 出现故障吗?这是否意味着我必须将 conversion 存储为其他无用的成员数据以使其也保持活动状态?如果是这样,对于仅用于保持活动状态的无用成员数据是否存在通用模式或命名约定?

因为我有多个构造函数,所以我不想将一堆特定于构造函数的成员数据附加到我的 class,因为这些数据大部分时间都不会被初始化。这一切闻起来都不对劲,但这是我的第一个 C++ 项目,所以 move semanticsownership semanticssmart pointersRAII,所有这些疯狂的东西都是对我来说很新,我正在努力全神贯注。

我来自 Java/Python/Go 背景。

  1. 是的,你必须让 bytestream 保持活动状态,典型的方法是将它存储在 unique_ptr 成员变量中。

  2. 是的,m_character_stream 将在 conversion 的生命周期之后使用您传递的指针,这是一个问题。所以是的,使 conversion 成为成员变量。

C++ 没有垃圾回收。使用 C++ 编程时,生命周期管理是绝对必要的。了解 RAII。