Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unique pointer and const correctness

I was not expecting this code to compile:

#include <iostream>
#include <memory>

class A
{
public:

    inline int get() const
    {
        return m_i;
    }

    inline void set(const int & i)
    {
        m_i = i;
    }

private:

    int m_i;
};

int main()
{
    const auto ptr = std::make_unique< A >();

    ptr->set( 666 ); // I do not like this line    D:<
    std::cout << ptr->get( ) << std::endl;

    return 0;
}

If ptr was a raw C pointer, I would be ok with that. But since I'm using a smart pointer, I can't understand what is the rationale behind this.

I use the unique pointer to express ownership, in Object Oriented Programming this could be seen as an object composition ("part-of" relationship).

For example:

class Car
{
    /** Engine built through some creational OO Pattern, 
        therefore it has to be a pointer-accessed heap allocated object **/
    std::unique_ptr< Engine > m_engine;
};

Or:

class A
{
    class Impl;

    std::unique_ptr< A::Impl > m_impl; // PIMPL idiom
};

If an instance of a class Car is constant, why the Engine should not be constant as well? If it was a shared pointer I would have been completely fine with that.

Is there a smart pointer who can reflect the behaviour I want?

like image 340
nyarlathotep108 Avatar asked Nov 06 '15 10:11

nyarlathotep108


People also ask

What is const-correctness in C?

In C, C++, and D, all data types, including those defined by the user, can be declared const , and const-correctness dictates that all variables or objects should be declared as such unless they need to be modified.

Why would you choose Shared_ptr instead of Unique_ptr?

Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. A shared_ptr is a container for raw pointers.

Is unique pointer a smart pointer?

There are three types of smart pointers in C++, shared pointers, unique pointers and weak pointers.

What is the difference between a shared pointer and a unique pointer?

unique ptr holds a single, unique reference to an instanced object. Its dtor frees the object. shared ptr holds a shared reference. Any number of shared ptrs can have the same reference.


1 Answers

It's pretty simple:

const auto ptr = std::make_unique< A >();

This means that the pointer itself is constant! But the object it holds is not. You can see it working the other way around...

A *const ptr = new A();

It's the same. The pointer is constant (can't be modified to point elsewhere), but the object is not.

Now, you probably meant that you want something like this, no?

const auto ptr = std::make_unique<const A>();

This will create a constant pointer to a constant A.

There's also this other way...

auto ptr = std::make_unique<const A>();

The object is constant, but not the pointer.

BTW: That "const-propagation" you talk about applies to C++, too, in the same way you stated it.

like image 67
3442 Avatar answered Sep 23 '22 07:09

3442