133d722a9Sopenharmony_ci{{#title std::shared_ptr<T> — Rust ♡ C++}}
233d722a9Sopenharmony_ci# std::shared\_ptr\<T\>
333d722a9Sopenharmony_ci
433d722a9Sopenharmony_ciThe Rust binding of std::shared\_ptr\<T\> is called **[`SharedPtr<T>`]**. See
533d722a9Sopenharmony_cithe link for documentation of the Rust API.
633d722a9Sopenharmony_ci
733d722a9Sopenharmony_ci[`SharedPtr<T>`]: https://docs.rs/cxx/*/cxx/struct.SharedPtr.html
833d722a9Sopenharmony_ci
933d722a9Sopenharmony_ci### Restrictions:
1033d722a9Sopenharmony_ci
1133d722a9Sopenharmony_ciSharedPtr\<T\> does not support T being an opaque Rust type. You should use a
1233d722a9Sopenharmony_ciBox\<T\> (C++ [rust::Box\<T\>](box.md)) instead for transferring ownership of
1333d722a9Sopenharmony_ciopaque Rust types on the language boundary.
1433d722a9Sopenharmony_ci
1533d722a9Sopenharmony_ci## Example
1633d722a9Sopenharmony_ci
1733d722a9Sopenharmony_ci```rust,noplayground
1833d722a9Sopenharmony_ci// src/main.rs
1933d722a9Sopenharmony_ci
2033d722a9Sopenharmony_ciuse std::ops::Deref;
2133d722a9Sopenharmony_ciuse std::ptr;
2233d722a9Sopenharmony_ci
2333d722a9Sopenharmony_ci#[cxx::bridge]
2433d722a9Sopenharmony_cimod ffi {
2533d722a9Sopenharmony_ci    unsafe extern "C++" {
2633d722a9Sopenharmony_ci        include!("example/include/example.h");
2733d722a9Sopenharmony_ci
2833d722a9Sopenharmony_ci        type Object;
2933d722a9Sopenharmony_ci
3033d722a9Sopenharmony_ci        fn create_shared_ptr() -> SharedPtr<Object>;
3133d722a9Sopenharmony_ci    }
3233d722a9Sopenharmony_ci}
3333d722a9Sopenharmony_ci
3433d722a9Sopenharmony_cifn main() {
3533d722a9Sopenharmony_ci    let ptr1 = ffi::create_shared_ptr();
3633d722a9Sopenharmony_ci
3733d722a9Sopenharmony_ci    {
3833d722a9Sopenharmony_ci        // Create a second shared_ptr holding shared ownership of the same
3933d722a9Sopenharmony_ci        // object. There is still only one Object but two SharedPtr<Object>.
4033d722a9Sopenharmony_ci        // Both pointers point to the same object on the heap.
4133d722a9Sopenharmony_ci        let ptr2 = ptr1.clone();
4233d722a9Sopenharmony_ci        assert!(ptr::eq(ptr1.deref(), ptr2.deref()));
4333d722a9Sopenharmony_ci
4433d722a9Sopenharmony_ci        // ptr2 goes out of scope, but Object is not destroyed yet.
4533d722a9Sopenharmony_ci    }
4633d722a9Sopenharmony_ci
4733d722a9Sopenharmony_ci    println!("say goodbye to Object");
4833d722a9Sopenharmony_ci
4933d722a9Sopenharmony_ci    // ptr1 goes out of scope and Object is destroyed.
5033d722a9Sopenharmony_ci}
5133d722a9Sopenharmony_ci```
5233d722a9Sopenharmony_ci
5333d722a9Sopenharmony_ci```cpp
5433d722a9Sopenharmony_ci// include/example.h
5533d722a9Sopenharmony_ci
5633d722a9Sopenharmony_ci#pragma once
5733d722a9Sopenharmony_ci#include <memory>
5833d722a9Sopenharmony_ci
5933d722a9Sopenharmony_ciclass Object {
6033d722a9Sopenharmony_cipublic:
6133d722a9Sopenharmony_ci  Object();
6233d722a9Sopenharmony_ci  ~Object();
6333d722a9Sopenharmony_ci};
6433d722a9Sopenharmony_ci
6533d722a9Sopenharmony_cistd::shared_ptr<Object> create_shared_ptr();
6633d722a9Sopenharmony_ci```
6733d722a9Sopenharmony_ci
6833d722a9Sopenharmony_ci```cpp
6933d722a9Sopenharmony_ci// src/example.cc
7033d722a9Sopenharmony_ci
7133d722a9Sopenharmony_ci#include "example/include/example.h"
7233d722a9Sopenharmony_ci#include <iostream>
7333d722a9Sopenharmony_ci
7433d722a9Sopenharmony_ciObject::Object() { std::cout << "construct Object" << std::endl; }
7533d722a9Sopenharmony_ciObject::~Object() { std::cout << "~Object" << std::endl; }
7633d722a9Sopenharmony_ci
7733d722a9Sopenharmony_cistd::shared_ptr<Object> create_shared_ptr() {
7833d722a9Sopenharmony_ci  return std::make_shared<Object>();
7933d722a9Sopenharmony_ci}
8033d722a9Sopenharmony_ci```
81