为构造函数初始化引用实例变量提供默认值

时间:2017-02-07 19:12:13

标签: c++ constructor reference

我有一个类Foo,它引用Bar作为实例变量。有没有办法让其中一个Foo构造函数创建一个Bar实例(因此Foo类的用户不需要自己显式创建Bar对象)?

我想做这样的事情:

class Foo {
  private:
    int size;
    Bar& bar; // shared by other objects
    //several other instance variables

  public:
    Foo(int s, Bar& b) : size(s), bar(b) {}

    // This, of course, doesn't work.  I can't think of an 
    // alternative that doesn't require users of Foo to 
    // create Bar
    Foo(int s) : size(s), bar(Bar(s)) {}
}

(在“现实生活中”,FooBar更复杂。BarFoo的朋友,其私有构造函数仅由{{1}使用每个Foo可以由几个Bar共享。这不是一个主要问题,我只是好奇它是否可以在没有指针的情况下完成。)

3 个答案:

答案 0 :(得分:3)

最简单的解决方案是在需要时分配Bar。添加成员std::unique_ptr<Bar>是实现此目标的最简单方法。我无法设想一个解决您的问题的系统,它不会给您的课程增加一些内存开销。即使不需要,您也必须考虑Bar的存储空间,或者您必须考虑某个状态来跟踪您的Bar是否在内部进行管理。使用unique_ptr会增加指向类的指针大小。

#include <memory>

class Foo {
private:
    std::unique_ptr<Bar> storage;
    Bar& bar;
    int size;

public:
    Foo(int s, Bar& b) : bar(b), size(s) {}
    Foo(int s) : storage(std::make_unique<Bar>(s)), bar(*storage), size(s) {}
};

更复杂的解决方案可能是为Bar提供一个包装器,它提供一个默认构造函数来负责初始化一个新实例。

请注意,在您的示例中,您不会按照声明的顺序初始化成员。无论您如何在初始化列表中对它们进行排序,成员都将按照声明的顺序初始化

答案 1 :(得分:0)

// This, of course, doesn't work.  I can't think of an 
// alternative that doesn't require users of Foo to 
// create Bar
Foo(int s) : size(s), bar(Bar(14)) {}

您可以使用默认的Bar对象,该对象可以是static的{​​{1}}成员变量,也可以是可以提供此类对象的任何其他类。

E.g。

Foo

答案 2 :(得分:0)

如果每个Foo都拥有自己的Bar - 对象(不是单个共享对象),那么您可以尝试以下操作:

class Foo {
private:
    Bar& bar; // shared by other objects
    int size;
    Bar* defaultBar;
    //several other instance variables

public:
    Foo(int s, Bar& b) : size(s), bar(b), defaultBar(nullptr) {}
    Foo(int s) : Foo(s, *(new Bar(14))) { defaultBar=&bar; };
    virtual ~Foo() {
        if (defaultBar)
            delete defaultBar;
    }
    void setBar(Bar &b) {
        if (defaultBar)
            delete defaultBar;
        defaultBar = nullptr;
        bar=b;
    }
};

希望这就是你要找的东西。