Reputation: 21022
I want to return two values, one of which is a new object. I can do this using std::pair
:
class A {
//...
};
std::pair<A*, int> getA()
{
A* a = new A;
//...
}
To make the code exception-safe, I would like to do:
std::pair<std::auto_ptr<A>, int> getA()
{
std::auto_ptr<A> a(new A);
//...
}
But this won't compile as the auto_ptr
cannot be copied without modifying the auto_ptr
being copied. Ok, this means auto_ptr
does not compose well like other types (in one more way). What is a good way of returning a new object in this case?
One alternative is to return a shared_ptr
and another is an inout reference. But I am looking for some other alternative. I can do something like:
class AGetter
{
void getAExecute()
{
//...
// set a_ and i_
}
std::auto_ptr<A> getA() const
{
return a_.release();
}
int getInt() const
{
return i_;
}
private:
std::auto_ptr<A> a_;
int i_;
};
Is there a better way?
Upvotes: 5
Views: 274
Reputation: 8447
Just create a new class and return that class
class Result
{
A* a;
int i;
public:
Result( A*a, int i ) : a(a), i(i) {
}
~Result() {
delete a;
}
// access functions, copy constructor, ...
};
Result getA() {
//...
return Result(new A, intValue);
}
Upvotes: 2
Reputation: 9806
A shared_ptr
would be ideal in that situation, but if you really don't want to use those you could return an auto_ptr
to a pair containing the object and the int instead.
Upvotes: 3
Reputation: 133008
Why not through two reference parameters?
class AGetter
{
// ..
void get(std::auto_ptr<A>& a, int& i)
{
a = a_.release();
i = i_;
}
// ..
};
Upvotes: 1
Reputation: 9705
There are two major ways to handle this problem:
shared_ptr
.auto_ptr
doesn't really work in these sorts of cases, as you discovered, but the new standard and Boost both contain reference-counted pointers that do what you want. Let us know what you don't like about shared_ptr
, and maybe we can suggest an alternative.
Upvotes: 5
Reputation: 4877
It's not pretty, but you could return the other value through a pointer or reference argument:
int i;
std::auto_ptr<A> a = getA(&i);
Upvotes: 1