Let's consider code below:
class A {
string a;
public A(string a) : a(a) { }
};
class B : public A {
public B(string a) : A(a) { }
};
int main() {
std::shared_ptr<A> x1 = std::make_shared<B>("x");
std::shared_ptr<A> x2 = std::make_shared<B>("x");
A* atom1 = x1.get();
A* atom2 = x2.get();
A* atom1X = std::make_shared<B>("x").get();
A* atom2X = std::make_shared<B>("x").get();
bool condition1 = (atom1 == atom2);
bool condition2 = (atom1X == atom2X);
}
The result is surprising me because condition1 is false but condition2 is true. Why? Can you explain what is going on here?
I was researching on the internet. I want to understand how it works
CodePudding user response:
A* atom1X = std::make_shared<B>("x").get(); // (1)
A* atom2X = std::make_shared<B>("x").get(); // (2)
In these definitions, std::make_share<B>("x")
creates a temporary std::shared_ptr
that ceases to exist at the end of the full expression (essentially at the next ;
). That means that the object each of these pointers points to gets destroyed immediately after being created.
By the time atom2X
is declared the object pointed to by atom1X
has been destroyed and its storage deallocated. It just so happens that the storage previously occupied by the object allocated in line (1) is exactly the right size to hold a B
object, so it gets re-used in line (2).
Essentially, if you remove all of the smart pointers, you can think of your code as being equivalent to this:
A* x1 = new B("x");
A* x2 = new B("x");
A* atom1 = x1;
A* atom2 = x2;
A* atom1X = new B("x");
delete atom1X;
A* atom2X = new B("x");
delete atom2X;