(Здесь есть три связанных вопроса)
Одна из самых неприятных вещей, с которыми я сталкиваюсь в C ++, — это случайная передача / копирование объекта, а затем удивление, почему его состояние не соответствует ожидаемому. Недавно у меня была ситуация, когда я проходил по указателю, но я не получал ожидаемого состояния, и оказалось, что мне нужно было передать указатель по ссылке, что меня действительно отбросило!
Могу ли я просто подтвердить, учитывая эту ситуацию:
MyClass x;
AnotherClass y;
y.passMyObjectSomewhere(x);
.
.
.
.
//Later on x is changed and I wish to see this change in y
x.modifyMyObject();
У меня есть следующие методы, чтобы сохранить состояние x
обновлено в y
:
MyClass* x = new MyClass();
y.passMyObjectSomewhere(x);
.
.
.
delete x;
или же
MyClass x;
y.passMyObjectSomewhere(&x);
или же
shared_ptr<MyClass> x(new MyClass());
y.passMyObjectSomewhere(x);
1) и все вышеперечисленные альтернативы сохранятся x
обновляется в y
объект, если я внесу изменения в x
вне y
?
2) Изменится ли вышеприведенное, если x был объектом для вектора или другой коллекции STL? Или применяются те же правила?
3) А как насчет класса, где указатель в конструкторе назначается члену данных:
class X{
public:
X(Something* x);
private:
Something* x;
}
X::X(Something* &y){
x = y;
}
Было бы y
должны быть переданы по ссылке здесь, потому что в противном случае копия указателя будет назначен? Я спрашиваю об этом из-за другого SO вопроса, который я задал здесь:
1) Да, они должны, если вы храните указатель на ваш х. Но будьте осторожны в ваших 2 первых примерах, y
кажется, может пережить x
, Указатель в y
не будет знать, что указанный объект будет удален, и это, безусловно, вызовет сбой:
MyClass* x = new MyClass();
y.passMyObjectSomewhere(x);
.
// update x
y.doesSomeActionOnX(); // no crash
delete x;
y.doesSomeActionOnX(); // crash
std::shared_ptr
это лучший вариант, поскольку он обрабатывает разделение собственности. Кстати, вы можете сделать:
auto x = std::make_shared<MyClass>();
2) везде одинаковые правила.
3) Ваша ссылка здесь абсолютно бесполезна.
X::X(Something* y)
{
this.y = y;
}
Других решений пока нет …