Returning a smart pointer?

Trying to write a getter function (yes I know they shouldn't be used) and I'm trying to return an std::unique_ptr<Paddle>. I have 4 of these Paddle objects in the class and I want to return them. How would I do this?

I know that if I just used a raw pointer, it would look like this
1
2
3
4
Paddle* Gunngine::getPaddles()
{
	return testing;
}


But I can't figure out how to properly return an std::unique_ptr.
Last edited on
What's the problem?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <memory>
using namespace std;

unique_ptr<int> f() {
    unique_ptr<int> p(new int);
    *p = 42;
    return p;
}

int main() {
    unique_ptr<int> p = f();
    cout << *p << '\n';
}


And what do you mean by "yes I know [getter functions] shouldn't be used"?
1
2
3
4
5
6
7
8
9
10
11
12
Class Game
{
Public:
Paddle();
~Paddle();

std::unique_ptr<Paddle> getPaddle();

Private:
std::unique_ptr<Paddle> leftPaddle;

};


So you're saying I can then do this?

1
2
3
4
std::unique_ptr Game::getPaddle()
{
  return leftPaddle;
}


Because I'm getting some errors when I run
1
2
3
4
if(getPaddle() == _leftPaddle)
{

}


I get a no operator "==" matches these opperands
Last edited on
I have no idea what to take seriously in the fake code you've posted.
It's riddled with errors, so obviously it won't work.
Maybe someone else can help you.
Sorry if that upset you. This is the beginner section so it should be no surprise to you or anyone else if someone posts something that doesn't make sense. Clearly I'm trying to learn, and clearly it's "fake" code. I'm here because I don't know how to achieve what I"m trying to do.


Paddle is an object of another class I made, if you didn't make sense of that. It's not a C++ data type that I'm trying to return.
Last edited on
You do have a fundamental issue in logic; the unique_ptr is unique.

When you assign a pointer:
1
2
3
4
std::unique_ptr<Gaz> foo = std::make_unique<Gaz>(42);
std::unique_ptr<Gaz> bar;
bar = foo;
assert( foo.get() == nullptr );

http://www.cplusplus.com/reference/memory/unique_ptr/operator=/
http://www.cplusplus.com/reference/memory/unique_ptr/unique_ptr/
http://www.cplusplus.com/reference/memory/unique_ptr/release/

In other words, if you return a Paddle from the Game, then the Game no longer has that Paddle.


Comparing two unique_ptr for equality should be trivial:
1
2
3
4
5
6
std::unique_ptr<Gaz> foo = ...;
std::unique_ptr<Gaz> bar = ...;

if ( foo == bar ) ...
// is the same as
if ( foo.get() == bar.get() )

If that test returns true, then you are in trouble. We can fabricate the situation:
1
2
3
Gaz* fubar = ...
std::unique_ptr<Gaz> foo(fubar);
std::unique_ptr<Gaz> bar(fubar); // Danger, Will Robinson! Danger! 

The foo and bar are distinct objects.
They both own the memory pointed to by fubar.
Each of them will delete the memory. Crash and burn.


If your compiler says "no operator == matches these opperands", then it should list the types of operands too. Do not ignore that information.
Last edited on
@keskiverto appreciate that write up. Makes sense now. I'll think of a different approach and read up a bit more on smart pointers.

Thanks!
@CGunn86, In the first post of the thread, it appears (edited since then) you asked a vague question returning unique_ptr not working and didn't fully explain the use-case. You didn't explain, for example, why you chose unique_ptr. So tpb, grasping at straws, took some time to come up with a concrete example of a working unique_ptr return.

You then replied a bunch of code that doesn't make sense, because, let's be honest -- you just made it up. While tpb's answer might've been a bit on the rude side, I, too, might be a bit offended by your impulsive reply -- what language are you even trying to write in that has capital "Class" , capital "Public:", capital "Private:", and then random Paddle constructor + destructor inside the Game class?

I highly suggest you try one of the online compilers like http://repl.it/languages/cpp to formulate "why doesn't this work?" code snippets. That would immediately reduce the 'whiteboarding' errors, at least.

But yeah, about the topic itself -- you'd benefit from explaining whether you're trying to return new Paddle objects each time and transfer ownership to the user. Perhaps you only wanted to give them read-only access to an existing Paddle and don't need null checks, in which case a const ref may be enough.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <memory>

using namespace std;

struct Paddle
{
    Paddle(int val) : val(val)
    {        
    }
    int val;
};

class Game
{
public:
    Game() : 
        left_paddle_(Paddle(42)),
        right_paddle_(new Paddle(50))
    {        
    }

    const Paddle& LeftPaddle() { return left_paddle_; }
    shared_ptr<const Paddle> RightPaddle() { return right_paddle_; }
    shared_ptr<Paddle> NullPaddle()  { return null_paddle_; }

private:
    Paddle left_paddle_;
    shared_ptr<Paddle> right_paddle_;
    shared_ptr<Paddle> null_paddle_;
};

int main() 
{
    Game g;
    cout << boolalpha;
    cout << "LeftPaddle value: " << g.LeftPaddle().val << endl;
    //g.LeftPaddle().val = 31; // error: assignment of member 'Paddle::val' in read-only object
    cout << "RightPaddle is null? " << (g.RightPaddle() == nullptr) << endl;
    //g.RightPaddle()->val = 33; // error: assignment of member 'Paddle::val' in read-only object
    cout << "   rightpaddle value: "<<g.RightPaddle()->val << endl;
    cout << "NullPaddle is null? "<< (g.NullPaddle() == nullptr) << endl;
}

https://repl.it/repls/MajesticInformalMacrolanguage

LeftPaddle value: 42
RightPaddle is null? false
   rightpaddle value: 50
NullPaddle is null? true

Topic archived. No new replies allowed.