std::unique_ptr
ps->comment();
}
return 0;
}
Here is the output:
Object created!
using auto_ptr
Object deleted!
Object created!
using shared_ptr
Object deleted!
Object created!
using unique_ptr
Object deleted!
Each of these classes has an explicit constructor taking a pointer as an argument. Thus, there is no automatic type cast from a pointer to a smart pointer object:
shared_ptr
double *p_reg = new double;
pd = p_reg; // not allowed (implicit conversion)
pd = shared_ptr
shared_ptr
shared_ptr
The smart pointer template classes are defined so that in most respects a smart pointer object acts like a regular pointer. For example, given that ps is a smart pointer object, you can dereference it (*ps), use it to access structure members (ps->puffIndex), and assign it to a regular pointer that points to the same type. You can also assign one smart pointer object to another of the same type, but that raises an issue that the next section faces.
But first, here’s something you should avoid with all three of these smart pointers:
string vacation("I wandered lonely as a cloud.");
shared_ptr
When pvac expires, the program would apply the delete operator to non-heap memory, which is wrong.
If Listing 16.5 represents the pinnacle of your programming aspirations, any of these three smart pointers will serve your purposes. But there is more to the story.
Smart Pointer Considerations
Why three smart pointers? (Actually, there are four, but we won’t discuss weak_ptr.) And why is auto_ptr being deprecated?
Begin by considering assignment:
auto_ptr
auto_ptr
vocation = ps;
What should the assignment statement accomplish? If ps and vocation were ordinary pointers, the result would be two pointers pointing to the same string object. That is not acceptable here because the program would wind up attempting to delete the same object twice—once when ps expires, and once when vocation expires. There are ways to avoid this problem:
• Define the assignment operator so that it makes a deep copy. This results in two pointers pointing to two distinct objects, one of which is a copy of the other.
• Institute the concept of
• Create an even smarter pointer that keeps track of how many smart pointers refer to a particular object. This is called
The same strategies we’ve discussed for assignment, of course, would also apply to the copy constructors.
Each approach has its uses. Listing 16.6 shows an example for which auto_ptr is poorly suited.
Listing 16.6. fowl.cpp
// fowl.cpp -- auto_ptr a poor choice
#include
#include
#include
int main()
{
using namespace std;
auto_ptr
{
auto_ptr
auto_ptr
auto_ptr
auto_ptr
auto_ptr
};
auto_ptr
pwin = films[2]; // films[2] loses ownership
cout << "The nominees for best avian baseball film are\n";
for (int i = 0; i < 5; i++)
cout << *films[i] << endl;
cout << "The winner is " << *pwin << "!\n";
cin.get();
return 0;
}
Here is some sample output:
The nominees for best avian baseball film are
Fowl Balls
Duck Walks
Segmentation fault (core dumped)
The “core dumped” message should help fix in your memory that a misused auto_ptr can be a problem. (The behavior for this sort of code is undefined, so you might encounter different behavior, depending on your system.) Here the problem is that the following statement transfers ownership from films[2] to pwin:
pwin = films[2]; // films[2] loses ownership