2016-10-25 10 views
1

Это, очевидно, дыра в моем самоучка информатики образования ...Какая разница между объектом, созданным в вызове функции и объект передается в

Конструктор для текстового управления (wxTextCtrl) в приложении WxWidgets имеет необязательный параметр для объекта валидатора. Все примеры кода создают валидатор «на лету» внутри конструктора для текстового управления.

Это работает ..

wxString value = L"0.0"; 
wxTextCtrl* _Text = new wxTextCtrl(this, wxID_ANY, value, 
    wxDefaultPosition, wxDefaultSize, 0, 
    wxTextValidator(wxFILTER_NUMERIC, &value)); 

Однако в моем конкретном случае я хочу создать валидатор в другой функции и передать его обратно, что не работает. В качестве промежуточного шага я пытался создать его как раз перед созданием wxTextCtrl и передать его в России, но это не работает, либо ...

wxString value = L"0.0"; 
wxValidator valid = wxTextValidator(wxFILTER_NUMERIC, &value); 
wxTextCtrl* _Text = new wxTextCtrl(this, wxID_ANY, value, 
    wxDefaultPosition, wxDefaultSize, 0, valid); 

Хотя это компилирует и запускает его не выполняет проверку. Может ли кто-нибудь объяснить, почему?

Прототип wxTextValidator требует постоянной ссылки ..

wxTextCtrl::wxTextCtrl ( wxWindow * parent, 
    wxWindowID id, 
    const wxString & value = wxEmptyString, 
    const wxPoint &  pos = wxDefaultPosition, 
    const wxSize & size = wxDefaultSize, 
    long style = 0, 
    const wxValidator &  validator = wxDefaultValidator, 
    const wxString & name = wxTextCtrlNameStr 
) 
+1

Третий параметр для ваших 'новых вызовов wxTextCtrl()' отличается: 'value' vs' _controls [name] '. Это намеренно? –

+0

@TavianBarnes нет, это была опечатка, я исправил ее. – marcp

ответ

7

Вы sliced на wxTextValidator объект, когда вы назначили его в переменную типа wxValidator, его базового класса. Чтобы это исправить, вам нужно сохранить более конкретный тип:

wxTextValidator valid = wxTextValidator(wxFILTER_NUMERIC, &value); 

Вы можете использовать auto, чтобы избежать повторения себя.

В качестве альтернативы, вы можете использовать lifetime extension, которое происходит при назначении временного к const ссылки:

const wxValidator& valid = wxTextValidator(wxFILTER_NUMERIC, &value); 

Это работает, потому что нет ни одной копии, и, следовательно, не отрезая.

Обратите внимание, что при разработке собственных классов часто рекомендуется предотвращать нарезку объектов, делая абстрактные абстрактные классы или создавая их (копии) конструкторы protected.

+0

Исправление, которое может быть следующим: 'wxTextValidator valid {wxFILTER_NUMERIC, & value};' или 'auto valid = wxTextValidator (wxFILTER_NUMERIC, & value);' (оба из которых также означают, что вы избегаете повторять себя способами, которые могут случайно выйти из синхронизации) , – ShadowRanger

+0

@ShadowRanger Действительно. Даже 'const wxValidator & valid = ...' будет работать из-за расширения продолжительности жизни. –

+0

@TavianBarns Я (очевидно) должен сделать еще немного чтения, но разве это не то, что происходит в рабочем примере? – marcp