Уникальный указатель и правильность const

Я не ожидал, что этот код скомпилируется:

#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;
}

Если PTR был сырой указатель C, я был бы в порядке с этим. Но так как я использую умный указатель, Я не могу понять, в чем причина этого.

Я использую уникальный указатель, чтобы выразить владение, в объектно-ориентированном программировании это можно рассматривать как композицию объекта (отношение «часть-часть»).

Например:

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;
};

Или же:

class A
{
class Impl;

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

Если экземпляр класса Car постоянная, почему двигатель не должен быть постоянным? Если бы это был общий указатель, я бы полностью согласился с этим.

Есть ли умный указатель, который может отражать поведение, которое я хочу?

6

Решение

Это довольно просто:

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

Это означает, что сам указатель постоянно! Но объект, который он держит, — нет. Вы можете видеть, что это работает наоборот …

A *const ptr = new A();

Это то же самое. Указатель является постоянным (не может быть изменен, чтобы указывать в другом месте), но объект не является.

Теперь вы, вероятно, имели в виду, что хотите что-то подобное, нет?

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

Это создаст постоянный указатель на постоянную A,

Есть и другой способ …

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

Объект является константой, но не указателем.

КСТАТИТо, что «const-распространение», о котором вы говорите, применимо и к C ++, так же, как вы это сформулировали.

13

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]