I had the (seemingly) bright idea of using extern template class std::shared_ptr<SomeWidelyUsedClass>
in stdafx.h immediately after #include <memory>
in order to prevent std::shared_ptr<SomeWidelyUsedClass>
from being redundantly instantiated in hundreds of files, figuring I could place template class std::shared_ptr<SomeWidelyUsedClass>
in a single .cpp in order to force a single instantiation and hopefully save on compile/link time. However, examination of the resulting .cod and .obj files shows that shared_ptr<SomeWidelyUsedClass>
code is being created everywhere anyway. But if I use this exact same technique with my own template class, it works as expected. Is there something special about shared_ptr
that precludes this use? Perhaps something in <memory>
itself that forces the compiler to create an instantiation before it reaches my extern template
statement (I'm very certain there's nothing higher up in stdafx.h that makes use of shared_ptr
)?
To clarify:
// stdafx.h; included in every cpp in the project
#include <memory>
#include "SomeWidelyUsedClass.h" // no shared_ptr in here
// I expect this to prevent instantiation of std::shared_ptr<SomeWidelyUsedClass>
// in all compilation units that include this, except the one below.
extern template class std::shared_ptr<SomeWidelyUsedClass>;
Then:
// ExplicitTemplateInstantiations.cpp
#include "stdafx.h"
// I expect this to cause std::shared_ptr<SomeWidelyUsedClass>
// to be instantiated in this compilation unit
template class std::shared_ptr<SomeWidelyUsedClass>;
And:
// SomeOtherFile.cpp
#include "stdafx.h"
#include "SomeWidelyUsedClass.h"
void foo()
{
// I expect that SomeOtherFile.obj will not include an instantiation of
// std::shared_ptr<SomeWidelyUsedClass> since it was declared extern in stdafx.h
std::shared_ptr<SomeWidelyUsedClass>(new SomeWidelyUsedClass());
}
Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. A shared_ptr is a container for raw pointers.
std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer.
The only difference between weak_ptr and shared_ptr is that the weak_ptr allows the reference counter object to be kept after the actual object was freed. As a result, if you keep a lot of shared_ptr in a std::set the actual objects will occupy a lot of memory if they are big enough.
All the instances point to the same object, and share access to one "control block" that increments and decrements the reference count whenever a new shared_ptr is added, goes out of scope, or is reset. When the reference count reaches zero, the control block deletes the memory resource and itself.
The standard says in §14.7.2/10:
Except for inline functions and class template specializations, explicit instantiation declarations have the effect of suppressing the implicit instantiation of the entity to which they refer.
I just checked in VS2013 and the implementation of std::shared_ptr<>
there has an inline constructor. This is probably the reason why your extern template
is ignored.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With