Возможно ли разделение с помощью Smart Pointers? - PullRequest
2 голосов
/ 09 октября 2009

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

class A
{
int something;
};

class B : public A
{
int stuff;
int morestuff;
};

int main()
{
    std::shared_ptr<B> b(new B());
    std::shared_ptr<A> a;
    a = b;
}

Насколько я понимаю, блок памяти, выделенный для объекта, на который указывает "b", остается тем же и не изменяется при назначении интеллектуальному указателю "a".

Пожалуйста, подтвердите или отклоните мое понимание, или дайте мне знать о любых подводных камнях, связанных с этим.

Ответы [ 2 ]

6 голосов
/ 09 октября 2009

Интеллектуальный указатель по-прежнему является указателем, поэтому такое назначение не приведет к нарезке. Разрезание происходит только при работе со значениями, а не с указателями. Тем не менее, обратите внимание, что шаблоны не знают об отношениях между элементами, на которые указывает точка, поэтому, даже если B получен из A, shared_pointer<B> не получен из shared_pointer<A>, поэтому назначение (автоматически) не получает автоматическое приведение, как с родными указателями.

Редактировать: уточнение в конечной точке.

Разрезание происходит со значениями, а не с указателями, поэтому (учитывая ваши определения A и B) что-то вроде:

A топор = b;

будет работать, но будет "разрезать" объект B, чтобы стать объектом A. Однако, если у вас есть какой-то шаблон, который содержит экземпляр элемента:

template <class T>
class holder { 
   T t_;
public:
   holder &operator=(T const &t) { 
       t_ = t;
       return *this;
   }
   holder &operator=(holder const &t) { t_ = t; return *this; }
};

Теперь, если мы попытаемся присвоить одно значение другому, подобное приведет к нарезке:

holder<A> ha;
holder<B> hb;

A a;
B b;

ha = a;
hb = b;
ha = hb;

мы НЕ получим нарезку. Вместо этого компилятор просто выдаст нам ошибку, сообщив, что holder<A> и holder<B> не являются связанными типами, поэтому назначение не может произойти - без добавления явного приведения он просто не будет компилироваться.

2 голосов
/ 09 октября 2009

Вы правы, но они не одинаковы: вы не можете оценить a->stuff.

...