-
February 23rd, 2016, 06:25 AM
#1
Smart pointers in C++
Hi,
Please have a look at the code below. Is this a smart pointer?
If so, why the first object, p1, is dangling at the end of the code? (That is p2 is deleted by the destructor but p1 remains, why?
Code:
#include <iostream>
#include <vector>
using namespace std;
template <class T> class my_auto_ptr {
T* myptr;
public:
my_auto_ptr(T* ptr = 0) : myptr(ptr) { }
~my_auto_ptr() {
delete myptr;
}
T* operator ->() const {
if (myptr != nullptr) return myptr;
else throw runtime_error("");
}
T& operator* () const {
if (myptr != nullptr) return *myptr;
else throw runtime_error("");
}
T* release() {
T* rptr = myptr;
myptr = 0;
return rptr;
}
};
//----------------------------------
int main() try {
my_auto_ptr<vector<int> > p1(new vector<int>(4, 5));
cout << p1->size() << endl;
my_auto_ptr<int> p2(new int(6));
cout << *p2 << endl;
return 0;
}
//-------------------------------
catch (...) {
cerr << "Exception occurred.\n";
return 1;
}
-
February 23rd, 2016, 06:46 AM
#2
Re: Smart pointers in C++
This code calls the constructor twice and the destructor twice.
Code:
#include <iostream>
#include <vector>
using namespace std;
template <class T>
class my_auto_ptr
{
T* myptr;
public:
my_auto_ptr(T* ptr = nullptr) : myptr(ptr)
{
cout << "constructor" << endl;
}
~my_auto_ptr() {
cout << "destructor" << endl;
delete myptr;
}
T* operator ->() const {
if (myptr != nullptr)
return myptr;
else
throw runtime_error("");
}
T& operator* () const {
if (myptr != nullptr)
return *myptr;
else
throw runtime_error("");
}
T* release() {
T* rptr = myptr;
myptr = nullptr;
return rptr;
}
};
int main()
{
try {
my_auto_ptr<vector<int> > p1(new vector<int>(4, 5));
cout << p1->size() << endl;
my_auto_ptr<int> p2(new int(6));
cout << *p2 << endl;
return 0;
}
catch (...) {
cerr << "Exception occurred.\n";
return 1;
}
}
Code:
constructor
4
constructor
6
destructor
destructor
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
February 23rd, 2016, 07:35 AM
#3
Re: Smart pointers in C++
There's no dangling pointer in the example you provided.
However, my_auto_ptr is not safe to use. Think about what will happen if you make a copy.
-
February 23rd, 2016, 10:35 AM
#4
Re: Smart pointers in C++
auto_ptr is a dangerous concept in C++, as it can implicitly transfer ownership on copy, which is not the usually expected semantic. That is why it was removed from the standard library.
The issue is that you need to either make it non-copyable, or have the copy constructor transfer owner ship (in which case it's not really a copy).
I'd suggest you also make your constructor explicit, so as to not accidently transfer steal ownership from a pointer.
If you do want to roll out your own auto_ptr, I'd suggest you instead model after boost's scoped_ptr. It's a bit more strict, but it's much harder to mess up with it. http://www.boost.org/doc/libs/1_60_0...scoped_ptr.htm
I assume this is a learning project. Otherwise, just use std::unique_ptr and be done with it.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
February 24th, 2016, 01:11 PM
#5
Re: Smart pointers in C++
auto_ptr is deprecated. (as you may know unique_ptr is the better choice as of c++14).
There is no point in re-implementing a deprecated construct, even if you fixed it,
I would suggest you name it something else.
Additionally it is not a smart pointer, and it can be confused with that concept.
Another sticking point of a smart pointer is to keep a reference count, and that it has a manager object
so that if there are valid references to it, it sticks around.
I realize that your probably trying to re-invent the wheel to understand how it might work, but
in addition, your implementation should only be used by you since you have the understanding that it
should only be used as an example of the concept.
Last edited by ahoodin; February 24th, 2016 at 01:21 PM.
ahoodin
To keep the plot moving, that's why.
-
February 24th, 2016, 01:47 PM
#6
Re: Smart pointers in C++
Originally Posted by ahoodin
Additionally it is not a smart pointer, and it can be confused with that concept.
Another sticking point of a smart pointer is to keep a reference count, and that it has a manager object
so that if there are valid references to it, it sticks around.
I disagree: reference counting is not the defining feature of a smart pointer, otherwise std::unique_ptr and boost::scoped_ptr would not be smart pointers. Rather, std::auto_ptr is a smart pointer as it is a class template that overloads operators so as to behave like a pointer, with the "smart" part coming from its usage for RAII. It just had shortcomings that made it dangerous, and obsolete with the advent of std::unique_ptr.
-
February 25th, 2016, 09:24 AM
#7
Re: Smart pointers in C++
Originally Posted by laserlight
I disagree: reference counting is not the defining feature of a smart pointer
Oh no I did not say that it was the defining feature, just part of the functionality of the smart pointer, using a manger object to delete a pointer with no references.
ahoodin
To keep the plot moving, that's why.
-
February 25th, 2016, 10:25 AM
#8
Re: Smart pointers in C++
Originally Posted by ahoodin
Oh no I did not say that it was the defining feature, just part of the functionality of the smart pointer, using a manger object to delete a pointer with no references.
It is not a mandatory feature of a smart pointer. The only requirement is "lifetime management". This includes unique_ptr (which has no manager object, and does not track references), or even weak_ptr (which does track references, but does not delete the pointer).
http://en.cppreference.com/w/cpp/memory
What you are talking about is a "shared" pointer, which is a specific class of smart pointer, but far from the only kind.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
February 27th, 2016, 02:15 AM
#9
Re: Smart pointers in C++
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|