Class B
expects to receive an instance of shared_ptr<IError>
.
Class A
implements IError
and is passed by value to the constructor of B
.
I would like to understand how this scenario is handled. How does the shared_ptr
as a template class handle the conversion to IError
?
In a simple case where B
receives shared_ptr<A>
I assume the copy constructor is called and the reference counter is increased. However since IError
is pure virtual a normal copy constructor invocation seems not to be case here?
// Example program
#include <iostream>
#include <string>
class IError
{
public:
virtual ~IError(){};
virtual void OnError() = 0;
};
class A : public IError
{
public:
A(){};
void OnError(){std::cout << "Error Occured" << std::endl;}
};
class B
{
public:
B(std::shared_ptr<IError> errorReporter): mErrorReporter(errorReporter){}
void Action(){mErrorReporter->OnError();}
private:
std::shared_ptr<IError> mErrorReporter;
};
int main()
{
auto objA = std::make_shared<A>();
auto objB = std::make_shared<B>(objA);
objB->Action();
}
Debugging time! Let's find out what happens by using the tools we have available as developers.
The memory of the shared_ptr objA
looks like this (type &objA
in the memory window; it will be replaced by its address):
It has a pointer to the object (000002172badd8e0
) and a pointer to the control block.
The control block looks like this (copy and paste the second value into a new memory window):
It has a pointer to the allocator (first 2 columns), the reference count (1) and the weak reference count (0 + offset 1).
After objB
has been created, the control block of objA
has changed to a reference count of 2:
And the shared_ptr objB
looks like this:
It points to the a shared pointer and to the control block.
The shared pointer in objB points to the same object as before (000002172badd8e0
), so no copy of the actual object has been made.
The control block of objB
indicates that objB
only has a reference count of 1:
a normal copy constructor invocation seems not to be case here?
Correct. No copy of the object is made, as we can confirm with a debugger. But a copy of the shared_ptr has been made.