5

Я не ожидал, что этот код скомпилировать:Уникальный указатель и сопзЬ правильность

#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 является постоянной, почему двигатель не должен быть постоянным, а? Если бы это был общий указатель, я был бы полностью в этом.

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

+1

'ptr-> set (666); // Мне не нравится эта строка D: <': Цитата дня;). – 3442

ответ

11

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

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>(); 

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

BTW: Это сообщение о «const-распространении», о котором вы говорите, относится и к C++, так же, как вы его заявили.

+0

Да, это было ясно, извините за то, что задал слишком много вопросов только в одном вопросе. Один из них был действительно: почему уникальная интеллектуальная указатель была сделана комитетом C++ в том, как он действует так же, как C raw-указатель? В чем смысл этого? – nyarlathotep108

+1

@ nyarlathotep108: В начале это кажется нечувствительным, пока вы не поймете, что указатель - это еще один объект, который удерживает адрес еще одного объекта. Иногда вы хотите изменить указатель на точку в другом месте, но он может указывать на постоянные объекты. В этом случае (они довольно распространены), этот шаблон сохранит вашу работу. – 3442

+0

Я не считаю это полезным сейчас, но я вижу, что ваш вопрос, вероятно, является действительным.Может быть, когда я хочу, чтобы они действовали так же, как действуют ссылки (с точки зрения соответствия const), я напишу свой собственный уникальный указатель, я не вижу другого пути. – nyarlathotep108