STL smart pointers

Hi,

I got into the smart pointer business and I have question which best demonstrated on a code taken directly from the forums tutorial. Namely the inheritance example polygon:

< // dynamic allocation and polymorphism
#include <iostream>
#include <memory>
using namespace std;

class Polygon {
protected:
int width, height;
public:
Polygon (int a, int b) : width(a), height(b) {}
virtual int area (void) =0;
void printarea()
{ cout << this->area() << '\n'; }
};

class Rectangle: public Polygon {
public:
Rectangle(int a,int b) : Polygon(a,b) {}
int area()
{ return width*height; }
};

class Triangle: public Polygon {
public:
Triangle(int a,int b) : Polygon(a,b) {}
int area()
{ return width*height/2; }
};

int main () {
//This works just fine
//Polygon * ppoly1 = new Rectangle (4,5);
//Polygon * ppoly2 = new Triangle (4,5);

//this works just fine as well
Polygon * ppoly1 = nullptr;
Polygon * ppoly2 = nullptr;

ppoly1 = new Rectangle (4,5);
ppoly2 = new Triangle (4,5);

//This does not work at all
///error: conversion from Rectangle to polygon
//unique_ptr<Polygon> ppoly1 = new Rectangle (4,5);
//unique_ptr<Polygon> ppoly2 = new Triangle (4,5);

//This works just fine
unique_ptr<Polygon> ppoly1(new Rectangle (4,5));
unique_ptr<Polygon> ppoly2(new Triangle (4,5));

// this one fails as well:
//error :no match for 'operator='
unique_ptr<Polygon> ppoly1 = nullptr;
ppoly1=new Rectangle (4,5);


ppoly1->printarea();
ppoly2->printarea();
//delete ppoly1;
//delete ppoly2;
return 0;
} >

So I am confused a bit about a unique pointer creation! Why does the assignment operator= fails but the constructor() works?

Thanks
If you look at the documentation for std::unique_ptr::operator=, it only allows assigning (copy or move) another unique_ptr or nullptr. Other than that you need to use the ctor.

To assign to a unique_ptr you can do this:
1
2
3
    unique_ptr<Polygon> ppoly1;
    // ...
    ppoly1 = unique_ptr<Polygon>(new Rectangle(4,5));


http://www.cplusplus.com/reference/memory/unique_ptr/operator=/
Last edited on
Hi,

Thanks this worked.
Note that unique_ptr is a move-only type. If you have two unique_ptr objects you cannot assign one to the other.

1
2
3
unique_ptr<Polygon> ppoly1(new Rectangle(4, 5));
unique_ptr<Polygon> ppoly2;
ppoly1 = ppoly2; // error 

If you want to transfer an object from one unique_ptr to another you will have to move it.

1
2
3
ppoly1 = std::move(ppoly2); // OK,
                            // ppoly1 will now point to what ppoly2 pointed 
                            // to before and ppoly2 will be set to nullptr. 


If you're using C++14 or C++17 you don't need to use new when working with unique_ptr, you can use std::make_unique instead.

This code

 
ppoly1 = unique_ptr<Polygon>(new Rectangle(4, 5));

could be written as

 
ppoly1 = make_unique<Rectangle>(4, 5);
Last edited on
Peter87 wrote:
Note that unique_ptr is a move-only type.

Good point. I can't believe I said "copy or move" about unique_ptr. Duh!
And make_unique is a nice addition.
Thanks guys,

very comprehensive intro to unique pointers! I am using C++11 at the moment but this will change very soon!
The move semantics was a good point! I made that error!

Topic archived. No new replies allowed.