The shared_ptr constructor from raw pointer is marked explicit (quick explanation: http://www.glenmccl.com/tip_023.htm). This is because once you put a pointer into a shared_pointer, it's lifetime is now managed by the shared_ptr. The authors feel it is very important that this is completely intentional, and rightly so. It can have nasty side effects if you don't.
//untested code
void foo(boost::shared_ptr<int> p)
{
(*p)++;
}
int main()
{
int* p = new int(5);
foo(p);
std::cerr << "p is now " << *p << std::endl; //oops, p has been deleted!!!
return 0;
}
-----Original Message-----
From: Marcel Loose [mailto:loose@astron.nl]
Sent: Friday, October 17, 2003 4:39 AM
To: boost-users@lists.boost.org
Subject: [Boost-users] [Q] shared_ptr c'tor
Hi,
I have a question related to the boost::shared_ptr constructor.
I want to be able to store boost::shared_ptr<Base> objects in
a std::vector. However, I don't want to bother my users with
the fact (implementation detail) that I'm using shared_ptrs
instead of raw pointers.
The simplified sample code below more or less clarifies what
I want. The code in line 27 is the code I would like to be
able to use. Below that line, several attempts to get the
code to compile can be found. I understand that line 32 won't
compile, because it is equivalent to line 27. However, line
37 left me puzzled. I would expect that the conversion of B*
to shared_ptr<B> would be trivial. Not so.
Is it really true that the only way to use shared_ptr in the
way I want is as in lines 46, 47? Or am I overlooking
something? And is line 41 equivalent to line 46?
Thanks in advance.
Regards,
Marcel Loose.
P.S.: I noticed that all code will compile if I omit the
"explicit" keyword in the constructor of shared_ptr, but I
don't consider that the proper way to solve the problem.
1:#include <boost/shared_ptr.hpp>
2:#include <vector>
3:
4:using namespace std;
5:using namespace boost;
6:
7:class Base
8:{
9:public:
10: Base() { /* ... */ }
11: virtual ~Base() {}
12:};
13:
14:class Derived : public Base
15:{
16:public:
17: Derived() { /* ... */ }
18: virtual ~Derived() {}
19:};
20:
21:
22:int main()
23:{
24: vector<shared_ptr<Base> > v;
25:
26: { // failes to compile:
27: v.push_back(new Derived()); // cannot
convert Derived*&
28: } // to
shared_ptr<Base>. Why?
29:
30: { // failes to compile:
31: Derived* d(new Derived()); // cannot
convert Derived*&
32: v.push_back(d); // to
shared_ptr<Base>. Why?
33: }
34:
35: { // failes to compile:
36: Base* b(new Derived()); // cannot convert Base*&
37: v.push_back(b); // to
shared_ptr<Base>. Huh?
38: } // Seems a
trivial conversion.
39:
40: { // OK, this
compiles, but is
41: shared_ptr<Derived> d(new Derived()); // it correct?
I.e. is conversion
42: v.push_back(d); //
shared_ptr<Derived> to
43: } //
shared_ptr<Base> trivial?
44:
45: { // OK, this
compiles, and is
46: shared_ptr<Base> b(new Derived()); // probably
what I meant.
47: v.push_back(b); // However, I
dislike the
48: } // verbosity.
49:
50: return 0;
51:}
Just to be complete, please find the compiler diagnostics below.
tBoost.cc: In function `int main()':
tBoost.cc:27: no matching function for call to `
std::vector<boost::shared_ptr<Base>,
std::allocator<boost::shared_ptr<Base>
::push_back(Derived*&)'
/usr/local/gcc-3.2.1/include/c++/3.2.1/bits/stl_vector.h:490:
candidates are:
void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp =
boost::shared_ptr<Base>, _Alloc =
std::allocator<boost::shared_ptr<Base> >]
tBoost.cc:32: no matching function for call to `
std::vector<boost::shared_ptr<Base>,
std::allocator<boost::shared_ptr<Base>
::push_back(Derived*&)'
/usr/local/gcc-3.2.1/include/c++/3.2.1/bits/stl_vector.h:490:
candidates are:
void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp =
boost::shared_ptr<Base>, _Alloc =
std::allocator<boost::shared_ptr<Base> >]
tBoost.cc:37: no matching function for call to `
std::vector<boost::shared_ptr<Base>,
std::allocator<boost::shared_ptr<Base>
::push_back(Base*&)'
/usr/local/gcc-3.2.1/include/c++/3.2.1/bits/stl_vector.h:490:
candidates are:
void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp =
boost::shared_ptr<Base>, _Alloc =
std::allocator<boost::shared_ptr<Base> >]
_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
-----------------------------------------------------------------------
DISCLAIMER: Information contained in this message and/or
attachment(s) may contain confidential information of Zetec, Inc.
If you have received this transmission in error, please notify
the sender by return email.
-----------------------------------------------------------------------