> Which one is better option
There are two approaches that could be taken:
One:
If the invariant (pre-condition) is that an object must be passed, pass by reference.
If the object may not be there, pass a pointer by value (
nullptr if there is no object).
This is very clean; it expresses the invariant in the declaration (header), in code rather than in comments.
Two:
If the object has a dynamic storage duration, always use pointer semantics.
Otherwise, follow approach one.
Both are acceptable alternatives; pick the one that appeals to you, and then be consistent about it.
Re. the original question: See:
http://en.cppreference.com/w/cpp/memory/enable_shared_from_this
Important:
Note that prior to calling shared_from_this on an object t, there must be a std::shared_ptr that owns t. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
#include <iostream>
#include <memory>
struct triangle : std::enable_shared_from_this<triangle>
{
static std::shared_ptr<triangle> create( /* constructor_args */ )
{ return std::shared_ptr<triangle>( new triangle( /* constructor_args */ ) ) ; }
std::shared_ptr<triangle> pointer() { return shared_from_this(); }
std::shared_ptr< const triangle > pointer() const
{ return const_cast<triangle*>(this)->pointer(); }
virtual ~triangle() { std::cout << "triangle " << this << " destructor\n" ; } // for tracing what is going on
// ...
protected: triangle( /* constructor_args */ ) /* init */
{ /* ... */ std::cout << "triangle " << this << " constructor\n" ; } // for tracing what is going on
};
int main()
{
auto ptr1 = triangle::create( /* constructor_args */ ) ;
std::cout << "ptr1 points to triangle at: " << ptr1.get() << '\n' ;
if(ptr1)
{
triangle& t = *ptr1 ;
auto ptr2 = t.pointer() ;
std::cout << "ptr2 points to triangle at: " << ptr2.get() << '\n' ;
const triangle& ct = t ;
std::shared_ptr<const triangle > ptr3 = ct.pointer() ;
std::cout << "ptr3 points to triangle at: " << ptr3.get() << '\n' ;
}
// uncomment the code below to engender undefined behaviour
/*
if(ptr1)
{
triangle& t = *ptr1 ;
auto ptr2 = std::shared_ptr<const triangle >( std::addressof(t) ) ;
std::cout << "ptr2 points to triangle at: " << ptr2.get() << '\n' ;
}
*/
}
|
http://coliru.stacked-crooked.com/a/d880219039795265