using std::shared_ptr

Dec 17, 2014 at 1:33am
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!
Dec 17, 2014 at 2:35am
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 Dec 17, 2014 at 2:37am
Dec 17, 2014 at 6:16am
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.

Dec 17, 2014 at 7:27am
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 ;
    // ...
};
Dec 17, 2014 at 7:43am
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!
Dec 17, 2014 at 11:42am
Cubbi wrote:
std::shared_ptr is very rarely useful (and very easily used inappropriately).
What? How could you use it inappropriately?
Dec 17, 2014 at 11:53am

"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.

Dec 17, 2014 at 6:39pm

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?
Dec 17, 2014 at 7:50pm
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.