с++ smart pointer
Прошу прощение за возможно глупый вопрос, но в интернете никакой информации не нашел, интересует информация по поводу smart pointer-ов.
#ifndef SHAPE_HPP
#define SHAPE_HPP
#include"base-types.hpp"
namespace test
{
class Shape
{
public:
virtual ~Shape() = default;
virtual double getArea() const noexcept = 0;
virtual rectangle_t getFrameRect() const noexcept = 0;
virtual point_t getCentre() const noexcept = 0;
virtual void move(const double x, const double y) = 0;
virtual void move(const point_t& center) noexcept = 0;
virtual void scale(const double coefficient) = 0;
virtual void rotate(double angle) noexcept = 0;
};
}
я хочу написать:
std::make_unique<std::shared_ptr<Shape>> pointer = std::make_unique<std::shared_ptr<Shape>[]>(0);
Мне преподаватель сказал, что из-за 0 - неопределенное поведение
std::shared_ptr<Shape> &CompositeShape::operator[](size_t index)
Также, сказали, что возвращать smart pointer-ы по ссылке - некорректно.
Можете ли вы подробно объяснить почему эти 2 ситуации некорректны.
Ответы (2 шт):
В первом случае (если правильно указать возвращаемый тип и расставить скобки) неопределённого поведения нет, потому что не запрещено выделять память под массив длины 0. Однако любой доступ к такому массиву вызовет UB, так что его можно только удалить.
Во втором случае возврат умного указателя по ссылке допускается, однако не рекомендуется, потому что при возврате по ссылке могут быть проблемы с подсчётом активных ссылок у std::shared_ptr, а никакого ускорения из-за RVO вы не получите.
Мне преподаватель сказал, что из-за 0 - неопределенное поведение
When the value of the expression is zero, the allocation function is called to allocate an array with no elements.
UB нет, преподователь не прав.
Правильно, все же, будет так:
std::unique_ptr<std::shared_ptr<Shape>[]> pointer = std::make_unique<std::shared_ptr<Shape>[]>(0);
unique_ptr, a неmake_uniquestd::unique_ptr<std::shared_ptr<Shape>[]>, а неstd::unique_ptr<std::shared_ptr<Shape>>
Но об этом вам должен был сказать компилятор.
Также, сказали, что возвращать smart pointer-ы по ссылке - некорректно
Проблема возврата ссылок к смарт поинтерам отношения не имеет. Если вы возвращаете ссылку на любой локальный нестатический объект, то это ошибка, в противном случае все нормально:
std::string global;
class Example {
std::string _s;
public:
const std::string& ok_1() const
{
return _s;
}
const std::string& ok_2() const
{
static const std::string s;
return s;
}
const std::string& ok_3() const
{
return global;
}
const std::string& fail_1() const
{
std::string s;
return s;
}
};
Так что возвращайте что угодно по ссылке, если уверены, что возвращаемый объект переживет ссылку(в Example::fail_1 s разрушится при выходе из функции, и пользователь получит "висячую" ссылку)