Я изучаю C ++ / CX, создавая приложение для магазина Windows. В качестве основы моих моделей просмотра я использую стандартный класс BindableBase и добавил к нему удобный метод SetProperty (к которому я привык в моих проектах на C #).
Теперь я ожидал, что я должен написать это так:
public ref class BindableBase : Windows::UI::Xaml::DependencyObject, Windows::UI::Xaml::Data::INotifyPropertyChanged,
{
public:
virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;
protected:
virtual void OnPropertyChanged(Platform::String^ propertyName);
private protected:
template <typename T>
bool SetProperty(T^ storage, T^ value, String^ propertyName)
{
if (storage == value)
{
return false;
}
storage = value;
OnPropertyChanged(propertyName);
return true;
}
};
Но это не работает, вид не будет обновляться. Но когда я изменил подпись метода SetProperty на это:
bool SetProperty(T& storage, T& value, String^ propertyName)
Это неожиданно работает, но я не могу понять, почему синтаксис ^ не работает.
C ++ / Cx-измы здесь не проблема. Вы получите такое же поведение, если будете использовать стандартные переменные C ++, как и при использовании дескрипторов C ++ / Cx (^).
Проблема заключается в параметрах значения по сравнению с эталонными параметрами. По умолчанию C ++ передает аргументы по значению. Изменения, внесенные в аргумент, являются локальными для вызываемой функции и не влияют на вызывающую функцию. Если вы пометите параметр с & затем параметр передается по ссылке, и изменения действительно влияют на вызывающего.
Это может быть понятнее, если вы переписываете пробел в своих аргументах:
bool SetProperty(T &storage, T &value, String ^propertyName)
Когда вы не используете & Синтаксис вы получаете T хранилище вызывающего (который должен быть классом ref, так как вы использовали ^), а затем перезаписываете это локально. Если вы прерветесь в отладчике, вы увидите, что хранилище настроено так, как вам нравится, но выйдите и сравните его в вызывающей программе, чтобы увидеть, что хранилище вызывающей стороны не изменилось. Удалите ^ s — SetProperty (T storage, T value, String ^ propertyName) — и он будет действовать так же с не-ref классами.
Когда вы используете & Синтаксис: вы получаете ссылку на хранилище T вызывающего, поэтому изменяется значение хранилища в переменной вызывающего.