I am writing a program with two parts. (A) sends an object to (B) which stores it, and once sent, (A) can only modify part of that object. I am stuck with pointers since I need low latency. Initially I had been using shared_ptr, but obviously (A) can modify the content in that ptr after (B) gets it, and I don't want (B) to make a copy of that object since it caused extra latency. I'm not familiar with all those smart pointers, but initially I'm thinking unique_ptr may do the trick. I'm wondering if this will work:
Can you give more details about what you're trying to do? This design seems rather unusual to me, and it seems like it'd be easy to screw something up.
What you have there will basically work, if I understood you correctly, although you need to fix a few things about how you move the std::unique_ptr around:
is A going to mess with it before it sends it to B? If not, can you solve this with just a const in the right place? (in this case, it may be references not pointers?)
also, is there an inverse solution where B gets it first and A picks it up *from* B? As in A.get returns B.get()?
Step 1: (A) creates a smart pointer of "Object" with some contents
Step 2: (A) sends the pointer to (B), who stores the pointer without copying the content.
Step 3: After a while, (A) modifies the changeable part of the "Object", and expect (B) to automatically pick up the change without sending it to (B) again.
Normally, using shared_ptr does the trick. However, there are parts of the "Object" that is unchangeable after sending to (B) in step 2. With shared_ptr, (A) can modify any field in "Object" of its own, and the change is automatically reflected in (B). Therefore, I am thinking of using unique_ptr for "Object" and shared_ptr for the changeable part of the "Object". However, I don't exactly know how to get it work in code.
#include <iostream>
#include <memory>
struct object
{
explicit object( int changeable = 0, int unchangeable = 0 )
: changeable(changeable), unchangeable(unchangeable) {}
int changeable ;
constint unchangeable ;
};
struct B
{
// (B) stores the pointer without copying the content.
void accept( const object* p ) { ptr = p ; }
// expect (B) to automatically pick up the change
void show_state_of_stored_object() const
{
if(ptr)
{
std::cout << "changeable == " << ptr->changeable
<< ", unchangeable == " << ptr->unchangeable << '\n' ;
// ptr->changeable = 0 ; // *** error: (B) is not allowed to modify the object
}
else std::cout << "there is no object\n" ;
}
const object* ptr = nullptr ; // pointer to const object
};
struct A
{
// Step 1: (A) creates a smart pointer of "Object" with some contents
explicit A( int v ) : ptr( std::make_unique<object>( v, v+12 ) ) {}
// Step 2: (A) sends the (raw) pointer to (B)
void send_to( B& b ) { b.accept( ptr.get() ) ; }
// Step 3: (A) modifies the changeable part of the "Object"
void modify_object() { ptr->changeable += 777 ; }
std::unique_ptr<object> ptr ;
};
int main()
{
A a(25) ;
B b ;
a.send_to(b) ; // send the (raw) pointer to B
b.show_state_of_stored_object() ; // changeable == 25, unchangeable == 37
// (A) modifies the changeable part of the "Object"
a.modify_object() ;
// expect (B) to automatically pick up the change
b.show_state_of_stored_object() ; // changeable == 802, unchangeable == 37
a.ptr = nullptr ; // kill the object
b.accept(nullptr) ; // notify (B) that the object is no longer there
b.show_state_of_stored_object() ; // there is no object
}
#include <iostream>
#include <memory>
struct object
{
explicit object( int changeable = 0, int unchangeable = 0 )
: changeable(changeable), unchangeable(unchangeable) {}
int changeable ;
constint unchangeable ;
};
struct B
{
// (B) stores the pointer without copying the content.
void accept( const std::shared_ptr< const object >& p ) { weak_ptr = p ; }
// expect (B) to automatically pick up the change
void show_state_of_stored_object() const
{
// try to get a temporary shared pointer to the object
auto ptr = weak_ptr.lock() ; // note: shared_ptr to const object
if(ptr) // if the object still exists
{
std::cout << "changeable == " << ptr->changeable
<< ", unchangeable == " << ptr->unchangeable << '\n' ;
// ptr->changeable = 0 ; // *** error: (B) is not allowed to modify the object
}
else std::cout << "the object has expired\n" ;
}
std::weak_ptr<const object> weak_ptr ; // smart pointer to const object
};
struct A
{
// Step 1: (A) creates a smart pointer of "Object" with some contents
explicit A( int v ) : ptr( std::make_shared<object>( v, v+12 ) ) {}
// Step 2: (A) sends the pointer to (B)
void send_to( B& b ) { b.accept(ptr) ; }
// Step 3: (A) modifies the changeable part of the "Object"
void modify_object() { ptr->changeable += 777 ; }
std::shared_ptr<object> ptr ;
};
int main()
{
A a(25) ;
B b ;
a.send_to(b) ; // send the pointer to B
b.show_state_of_stored_object() ; // changeable == 25, unchangeable == 37
// (A) modifies the changeable part of the "Object"
a.modify_object() ;
// expect (B) to automatically pick up the change
b.show_state_of_stored_object() ; // changeable == 802, unchangeable == 37
a.ptr = nullptr ; // kill the object
b.show_state_of_stored_object() ; // the object has expired
}