using std::shared_ptr

Hello,

I'd like to have a shared_ptr type object in a class, and one of the class' member functions should assign who the shared_ptr points to.

In code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A
{
public:
std::shared_ptr<some_type> Shared_Pointer;

void Assign_Pointer();
};

void A::Assign_Pointer()
{
some_type Some_Type;
//how do I "point" the shared_ptr to Some_Type here?
}


I knew how to do this before using plain old pointers and new; the problem is that the more I read up on it the more I realize that there is never a reason to NOT use a shared_ptr. Any idea of what to do?

Thanks!
It's no different from any other pointer, you assign it:

1
2
3
4
void A::Assign_Pointer()
{
    Shared_Pointer = std::make_shared<Some_Type>();
}


hyperfine wrote:
the more I read up on it the more I realize that there is never a reason to NOT use a shared_ptr

std::shared_ptr is very rarely useful (and very easily used inappropriately). Look into using std::unique_ptr

PS: also look into using constructors, this "A::Assign_Pointer()" should not exist as written.
Last edited on
Thanks, I must have actually been thinking of unique_ptr's when I posted.

The reason I do not assign the pointer when A is constructed is that in my program Some_Type is a file stream. When the file stream is called, it has to be initialized with a string for the location of the file. Thus, the issue is that when A is initialized, the file location is not known. A has a member function that asks the user to input the name of the file. It seems that (given the way I've designed my program), it is not possible to get away without using a pointer of some sort, and it's not possible to assign the value of the pointer in the class constructor.

C++11 streams are MoveConstructible and MoveAssignable.
With conforming implementations (read: non-GNU implementations):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct A
{
    A() = default ;

    explicit A( const std::string& path, std::ios::openmode open_mode = std::ios::in|std::ios::out )
           : file( path, open_mode ) {}

    explicit A( std::fstream&& f ) : file( std::move(f) ) {} // note: the GNU library chokes on this

    bool open() const { return file.is_open() ; }

    void open( const std::string& path, std::ios::openmode open_mode = std::ios::in|std::ios::out )
    { file.open( path, open_mode ) ; }

    void assign( std::fstream&& f ) { std::swap( file, f ) ; } // note: the GNU library chokes on this

    // ....

    private: std::fstream file ;
    // ...
};
Thank you for the reply. I will look into MoveConstructible and MoveAssignable properties. I didn't mention this in the previous post, but the stream (and file) are actually QT types: QTextStream and QFile. If those also have the property you mentioned I will look into exploiting that. Thank you!
Cubbi wrote:
std::shared_ptr is very rarely useful (and very easily used inappropriately).
What? How could you use it inappropriately?

"Shared pointers are as bad as globals." Sean Parent.
http://channel9.msdn.com/Events/GoingNative/2013/Cpp-Seasoning

http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/

shared_ptr clouds resource ownership and lifetime.


It's no different from any other pointer, you assign it:

1
2
3
4



void A::Assign_Pointer()
{
Shared_Pointer = std::make_shared<Some_Type>();
}




Is there a pre-C++14 equivalent to std::make_shared for unique_ptr?
No, but you can write one yourself. For example, implementation for singular objects (does not support arrays)
1
2
3
4
5
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique
Topic archived. No new replies allowed.