如何通过共享的PTR访问类的成员函数?

问题描述

我有两个类,foobar,其中bar包含一个指向foo的指针,如下所示。

#include<iostream>
#include<memory>
class foo {
private:
  int num{4};
public:
  void sum(const int& to_add) {num += to_add;}
  int access_num() {return num;}
};
class bar {
private:
  std::shared_ptr<foo> ptr;
public:
  void change_ptr(foo& f) {
    auto new_ptr = std::make_shared<foo>(f);
    ptr = std::move(new_ptr);
  }
  std::shared_ptr<foo> access_ptr() { return ptr; }
};

如果我想通过sum()中的指针执行foo的成员函数bar,该怎么做? 目前正在尝试

  foo f;
  std::shared_ptr<bar> bar_ptr = std::make_shared<bar>();
  bar_ptr->change_ptr(f);
  // Add three to the int stored in f via the pointer
  bar_ptr->access_ptr()->sum(3);
  std::cout << f.access_num() << std::endl;

不起作用,输出4。

解决方法

此代码

void change_ptr(foo& f) {
    auto new_ptr = std::make_shared<foo>(f); // copy constructor
    ptr = std::move(new_ptr);
}  

调用复制构造函数在堆上创建foo的实例,并使用std::shared_ptr对其进行管理。如果删除foo声明中的副本构造函数,则可以检查它。该代码将无法编译。请注意,您必须至少提供一个默认的构造函数,因为如果您明确删除了复制构造函数,则零规则将不起作用。

class foo {
private:
    int num{4};
public:
    foo() = default;
    foo(foo const &other) = delete;
    void sum(const int& to_add) {num += to_add;}
    int access_num() {return num;}
};

foo f是存储在堆栈中的自动变量。使用std::shared_ptr对其进行管理没有太大用处。您可能需要在堆上创建一个foo实例,并使用std :: shared_ptr对其进行处理:

#include<memory>

class foo {
private:
    int num{4};
public:
    void sum(const int& to_add) {num += to_add;}
    int access_num() {return num;}
};

class bar {
private:
    std::shared_ptr<foo> ptr;
public:
    void change_ptr(std::shared_ptr<foo> f) {
        ptr = std::move(f); // f is already a copy,so we can safely move it
    }
    std::shared_ptr<foo> access_ptr() { return ptr; }
};

int main() {
    auto f = std::make_shared<foo>();
    std::shared_ptr<bar> bar_ptr = std::make_shared<bar>();
    bar_ptr->change_ptr(f);
    bar_ptr->access_ptr()->sum(3);
    std::cout << f->access_num() << std::endl;
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...