I was just messing around with unique_ptrs and vectors and it seemed like the author of the article is incorrect about one of the things he said:
Quote
This seems reasonable, but doing this gets me into a gray area: Who owns the pointer? Will the container destroy it at some point in its lifetime? Or is it still my job do so?
The rules of using unique_ptr prohibit this kind of code, and trying to compile it will lead to the classic cascade of template-based compiler errors
The rules of using unique_ptr prohibit this kind of code, and trying to compile it will lead to the classic cascade of template-based compiler errors
But I just compiled and ran this code fine with no warnings or errors:
// UniquePtr.cpp
// Example usage of the C++11 feature: std::unique_ptr.
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
// Test class to log what unique_ptr is actually doing.
class Trace
{
// Trace object count.
static size_t count;
// Object id number.
size_t id;
public:
Trace() : id(++count) { cout << "Creating Trace object " << id << endl; }
Trace(const Trace& t) : id(++count)
{
cout << "Creating Trace object " << id << " as a copy of Trace object " << t.id << endl;
}
~Trace() { cout << "Destroying Trace object " << id << endl; --count; }
static size_t getCount() { return count; }
friend ostream& operator<<(ostream& out, const Trace& t)
{
return out << "Trace object " << t.id;
}
};
size_t Trace::count = 0;
int main()
{
{
const size_t MAX = 10;
vector<unique_ptr<Trace>> v;
for(size_t i = 0; i < MAX; ++i)
v.push_back(unique_ptr<Trace>(new Trace));
for(size_t i = 0; i < MAX; ++i)
cout << "v[" << i << "] = " << *(v[i]) << endl;
}
}
Compile command line:
Quote
g++ -Wall -ansi -std=c++0x UniquePtr.cpp -o UniquePtr
And here's the output:
Quote
./UniquePtr
Creating Trace object 1
Creating Trace object 2
Creating Trace object 3
Creating Trace object 4
Creating Trace object 5
Creating Trace object 6
Creating Trace object 7
Creating Trace object 8
Creating Trace object 9
Creating Trace object 10
v[0] = Trace object 1
v[1] = Trace object 2
v[2] = Trace object 3
v[3] = Trace object 4
v[4] = Trace object 5
v[5] = Trace object 6
v[6] = Trace object 7
v[7] = Trace object 8
v[8] = Trace object 9
v[9] = Trace object 10
Destroying Trace object 1
Destroying Trace object 2
Destroying Trace object 3
Destroying Trace object 4
Destroying Trace object 5
Destroying Trace object 6
Destroying Trace object 7
Destroying Trace object 8
Destroying Trace object 9
Destroying Trace object 10
Creating Trace object 1
Creating Trace object 2
Creating Trace object 3
Creating Trace object 4
Creating Trace object 5
Creating Trace object 6
Creating Trace object 7
Creating Trace object 8
Creating Trace object 9
Creating Trace object 10
v[0] = Trace object 1
v[1] = Trace object 2
v[2] = Trace object 3
v[3] = Trace object 4
v[4] = Trace object 5
v[5] = Trace object 6
v[6] = Trace object 7
v[7] = Trace object 8
v[8] = Trace object 9
v[9] = Trace object 10
Destroying Trace object 1
Destroying Trace object 2
Destroying Trace object 3
Destroying Trace object 4
Destroying Trace object 5
Destroying Trace object 6
Destroying Trace object 7
Destroying Trace object 8
Destroying Trace object 9
Destroying Trace object 10
I'm not sure if he's talking about something slightly different. In the article his simple example is just:
std::unique_ptr<foo> q( new foo(42) ); v.push_back( q );
I don't see there being much difference in first saving the dynamically allocated memory in a unique_ptr object and then pushing that onto the vector, or doing it the way I did in the code above.
This post has been edited by vividexstance: 27 June 2012 - 11:27 AM

New Topic/Question



MultiQuote







|