您可以在同一对象中具有对成员std :: shared_ptr <variable>的成员引用吗?

时间:2019-03-29 09:44:39

标签: c++ memory-management

我正在创建一个C ++类A,该类具有对象成员变量B,默认情况下不应实例化该成员变量。我不喜欢使用指针语法,因为类B在operator()中依赖很多,并且代码变得如此混乱。

为了使用引用作为成员变量,但是每次我想通过引用访问对象时,都会遇到分段错误。

有可能做这项工作吗?

class SomeClass {
    public:
        SomeClass(int argToInitSomeOtherClass);
    void someOtherFunction();

    private:
        std::shared_ptr < SomeOtherClass > MemberObject;
    SomeOtherClass & MemberObjectReference = * MemberObject;
};

class SomeOtherClass {
    public:
        SomeOtherClass(int initArg) {
            this - > member = initArg;
        };
    void whatever() {}; // I do nothing

    private:
        int member;
};

SomeClass::SomeClass(int argToInitSomeOtherClass) {
    MemberObject = std::make_shared < SomeOtherClass > (argToInitSomeOtherClass)
}

void SomeClass::someOtherFunction() {
    MemberObjectReference.whatever(); // Segmentation fault
}

如果有一种方法可以以非静态方式保存成员对象并在没有默认值的情况下实例化它,这也解决了我的问题,但我认为这是不可能的。

1 个答案:

答案 0 :(得分:1)

我不确定OP到底打算实现什么。

我会寻找另一种设计,因为在我看来,OP的方法脆弱且易于在源代码更改最少的情况下中断。

但是,OP的实际错误是恕我直言,构造函数中的错误初始化:

必须在共享指针初始化后获取引用。另外,我使共享指针const强调一旦重新分配共享指针,它将破坏(引用将变得悬而未决)。 (const会使这种尝试成为编译器错误。)

在参考指针对象时(无论是原始指针还是智能指针),都应谨慎考虑指针对象的寿命。 C ++中的引用本身并不执行此操作-这是作者的责任。

OP的固定示例:

#include <memory>
#include <iostream>

struct SomeOtherClass {
  int member;
  explicit SomeOtherClass(int initArg = 0): member(initArg) { }
  void whatever() { std::cout << "SomeOtherClass::member: " << member << '\n'; }
};

class SomeClass {
  public:
    explicit SomeClass(int argForOther);
    SomeClass(const SomeClass&) = delete;
    SomeClass& operator=(const SomeClass&) = delete;
    void someOtherFunction();
  private:
    const std::shared_ptr<SomeOtherClass> MemberObject;
    SomeOtherClass &MemberObjectReference;
};

SomeClass::SomeClass(int argForOther):
  MemberObject(std::make_shared<SomeOtherClass>(argForOther)),
  MemberObjectReference(*MemberObject)
{ }

void SomeClass::someOtherFunction()
{
    MemberObjectReference.whatever(); // Segmentation fault fixed
}

int main()
{
  SomeClass someClass(123);
  someClass.someOtherFunction();
  return 0;
}

输出:

SomeOtherClass::member: 123

Live Demo on coliru