【问题标题】:Initialize member variable without making a new copy初始化成员变量而不创建新副本
【发布时间】:2013-07-26 22:07:17
【问题描述】:

我有一个班级需要了解一些大型数据结构。因此,我创建了一个构造函数,它接受对该大型数据结构的引用并使用它来初始化成员变量,如下所示:

 class Foo {
 public:
   BigStruct m_bigstruct;

   Foo(BigStruct &inBigStruct) : m_bigstruct(inBigStruct) {}
 };

这似乎复制了inBigStruct,但我不想浪费这些资源,因为BigStructs 很大。有没有更标准的方法可以让 Foo 可以使用 inBigStruct 的内容而不复制它?我知道我可以做到:

 class Foo {
 public:
   BigStruct* m_bigstruct;

   Foo(BigStruct* inBigStruct) : m_bigstruct(inBigStruct) {}
 };

这是使inBigStruct 可用于Foo 而无需复制的常用方法吗?如果不是,那是什么?

【问题讨论】:

  • 你也可以持有Bigstruct的引用。
  • 在 c++11 之前,语言中没有内置方法可以知道何时可以安全地从另一个对象中窃取。我想你可以写一个steal(BigStruct& other) 函数。使用 c++11 编写移动构造函数:msdn.microsoft.com/en-us/library/dd293665.aspx
  • @BoBTFish:C++03 中通常的习惯用法是实现和使用swap,而不是一个名为steal 的函数。不过,这几乎是相同的事情:调用者会判断是否可以与原件混淆。
  • 既然我们提到了 C++11,我应该指出,我通过使用 lambda 轻松解决了 C++11 中真正的问题——函子。捕获时无需复制。

标签: c++ class initialization


【解决方案1】:

C++2011的做法是移动对象,例如:

Foo::Foo(BigStruct const& argument): m_bigstruct(argument) {}       // copies
Foo::Foo(BigStruct&& argument): m_bigstruct(std::move(argument)) {} // moves

当然,这假设BigStruct 有一个合适的移动构造函数。根据传递的是临时的(或通过std::move() 看起来像临时的东西)还是左值,对象将被移动或复制:如果您有另一个对对象的引用,您通常不想窃取对象,但复制它。

【讨论】:

    【解决方案2】:

    如果您确定 Foo 活着时它不会失效,您可以存储引用。

    class Foo {
     public:
       /*const*/ BigStruct& m_bigstruct;
    
       Foo(BigStruct &inBigStruct) : m_bigstruct(inBigStruct) {}
     };
    

    【讨论】:

    • @BoBTFish,我不这么认为。
    • @BoBTFish 也许不是更好,但表达了不同的意图:成员在其生命周期中仅引用一个对象。
    • 这似乎是最合乎逻辑的事情,也是最危险的事情。我实际上只是想要一个对 inBigStruct 的引用,但我也不能保证在此期间某些东西不会使 inBigStruct 引用的实例无效。当然,如果原件因任何原因失效,那么继续下去也没有多大意义……
    • @Fadecomic,如果有人可以破坏原始对象,您必须有副本才能工作。你也可以考虑shared_ptrbtw
    猜你喜欢
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 2014-09-08
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多