std::make_shared
always creates a brand new object. That is,
sptr = make_shared<A>(b);
is more like
A* p1 = new A(b);
and not like
A* p2 = &b;
p1
and the return value of make_shared
do not point at b
at all.
문제
I was debugging an issue in some larger code and realized something strange about smart pointers and their polymorphic properties. This is best seen through the simple example:
#include <iostream>
#include <memory>
using namespace std;
class A {
public:
virtual void who() {cout << "I am class A" << endl; };
};
class B : public A{
public:
void who() {cout << "I am class B" << endl; };
};
int main(int argc, char *argv[])
{
B b;
A * aptr = &b;
aptr->who(); //Output: I am class B
B * bptr = &b;
bptr->who(); //Output: I am class B
shared_ptr<A> sptr;
sptr = make_shared<A>(b);
sptr->who(); //Output: I am class A
sptr = make_shared<B>(b);
sptr->who(); //Output: I am class B
return 0;
}
The first two outputs makes sense to me, but why can I access the member function defined in A (see the third output) when the only object I have initialized is of type B? In some sense, this is a nice trick for accessing members of the base class of an object of derived type. However, this still feels a bit spooky to me...
Can anyone explain why this behavior is possible with smart pointers but not regular pointers?
해결책
std::make_shared
always creates a brand new object. That is,
sptr = make_shared<A>(b);
is more like
A* p1 = new A(b);
and not like
A* p2 = &b;
p1
and the return value of make_shared
do not point at b
at all.
다른 팁
The following statement:
sptr = make_shared<A>(b);
is basically the same as:
sptr = shared_ptr(new A(b));
Instead of creating a shared_ptr from a pointer to B
, you are creating a new A
object with the copy constructor of A
.
make_shared<A>(b)
uses b
to construct an object of type A
, and points to that newly constructed object. This slices the B
object, so the shared_ptr
truly points to an A
.