将shared_ptr从另一个函数传递给一个函数

问题描述 投票:0回答:1

很久之后我又回到了C++,继承了一个代码库,其中一部分具有以下代码的结构。我有两个对象,

Wrapped
Wrapper
,正如所料,
Wrapper
包裹
Wrapped
。有两个工厂方法
make_Wrapper
make_Wrapped
,它们返回指向相应对象的指针。

在下面的代码中,我观察到,使用

Case1
shared_ptr
不起作用,而使用普通 C++ 指针的
Case2
则有效。我所说的“不起作用”,是指在 Case1 中
nz_=10
中的值
wrapped
被垃圾替换,而在 Case2 中它等于 10。我可以通过
wrapper.nz_
main
中打印
outside_wrapper->print()
的值来检查这一点。

我认为这是因为shared_ptr指向的对象在这个函数

make_Wrapper
退出后被删除了。我说得对吗?

通过

shared_ptr
将对象从
make_Wrapper
传递到
Wrapper
构造函数的正确方法是什么?

#include <iostream>
#include <memory>
#include <functional>

// this is struct which is to be wrapped
struct Wrapped {
  int nz_;
  Wrapped(int nz):nz_(nz) {}
  inline virtual void destroy() { delete this; };
};

// this is the wrapper
struct Wrapper {
  Wrapper(Wrapped& wrapped):wrapped_(wrapped){}
  Wrapped& wrapped_;
  
  inline virtual void destroy() { delete this; };
  
  void print() {
    std::cout << "from wrapper: wrapped_.nz_=" << wrapped_.nz_<<std::endl;
  }
};

// factory function which returns pointer to wrapped object
Wrapped* make_Wrapped(int nz) {
  return new Wrapped(nz);
}


// factory function which returns pointer to wrapper object
Wrapper* make_Wrapper(int nz) {

  // Case 1
  // following line does not work - I think the object pointed to by the shared_ptr is deleted after this function exits
  std::shared_ptr<Wrapped> wrapped(make_Wrapped(nz), std::mem_fun(&Wrapped::destroy));

  // Case 2
  // following line works
  // Wrapped *wrapped = new Wrapped(nz);
  
  std::cout<<" from make_Wrapper "<<(*wrapped).nz_<<std::endl;
  return new Wrapper(*wrapped);
}

int main() {
    int nz=10;
    char tempbuffer[80];
    
    std::shared_ptr<Wrapper> outside_wrapper(make_Wrapper(nz), std::mem_fun(&Wrapper::destroy));
    outside_wrapper->print();

    std::cout << "Enter something to continue ..." << std::endl;
    std::cin >> tempbuffer;
    return 0;
}

c++ shared-ptr
1个回答
0
投票

一旦一个对象被

shared_ptr
包裹,当指向它的最后一个
shared_ptr
被销毁时,它就会被销毁,这发生在
make_Wrapper
的末尾。

解决方案:

让 Wrapper 存储

shared_ptr
而不仅仅是一个参考。

struct Wrapper {
    Wrapper(std::shared_ptr<Wrapped> wrapped) :wrapped_(wrapped) {}
    std::shared_ptr<Wrapped> wrapped_;

    inline virtual void destroy() { delete this; };

    void print() {
        std::cout << "from wrapper: wrapped_.nz_=" << wrapped_->nz_ << std::endl;
    }
};

// factory function which returns pointer to wrapper object
Wrapper* make_Wrapper(int nz) {

    // Case 1
    // following line does not work - I think the object pointed to by the shared_ptr is deleted after this function exits
    std::shared_ptr<Wrapped> wrapped(make_Wrapped(nz), std::mem_fun(&Wrapped::destroy));

    std::cout << " from make_Wrapper " << (*wrapped).nz_ << std::endl;
    return new Wrapper(wrapped);
}
© www.soinside.com 2019 - 2024. All rights reserved.