2017-02-15 24 views
2

、私はQT GUIプロジェクトにカスタムQValidatorを書いていますし、私の理解では、私がQValidatorクラスを拡張する必要があるということである。なぜなら:書き込み

void setValidator(const QValidator *); 

QValidatorサブクラスを渡す必要があります。 問題が関数ということである。

virtual QValidator::State validate(QString& input, int& pos) const Q_DECL_OVERRIDE; 

がconstのですが、私は私のサブクラスで検証状態に書き込む必要がある、と私はこのためにconst属性のいずれかのメンバ変数に書き込むことはできません。このAPIの制約を回避するにはどうすればよいですか?

私はこのような何かをやっている:

QValidator::State IPv4Validator::validate(QString &input, int &pos) const 
{ 
    auto validationResult = QRegExpValidator::validate(input, pos); 
    // custom logic here: 
    myMemberVariable = something(validationResult); 
    // more logic 
    // more logic 
    // more logic 

    return validationResult; 
} 

感謝を事前に!

+8

基本的な検証によってオブジェクトの状態が変更される必要がある場合は、Wrong Way™でライブラリを使用しています。それはしないでください。技術的な回避策(状態へのポインタ、 'mutable'状態、' const_cast'、Cコードの呼び出し)がありますが、**はありません**。どのようにQtを誤って使用しているのかを調べ、あなたのやり方を修正してください。 'const' -nessを回避することは、コンパイラーが互換性のない型を黙ってシャットダウンするときにCのキャストをドロップするのと同じです。それは、現実が反対で、悲しみの結果が多いときに、「私が実際にやっていることを本当に知っているので、起こりそうな問題について私に教えてはいけません。 –

+2

複数の入力に対して同じバリデータを使うことができるので、状態をQValidatorに格納しないでください。状態では不可能です! – JvO

+0

私はあなたのポイントを見ます。 – androidu

答えて

0

あなたのコメントを読んだあと、QValidatorサブクラスの外でカスタムロジックを委任する必要があることに気付きました。あなたのお返事ありがとうございます!彼らは私が間違っていたことを理解するのを助けました。

3

メンバー変数mutableを宣言するか、const_cast(安全でない)を使用して、const関数にメンバー変数を書き込むことができます。

struct A { 
    void foo() const { 
     a = 3; 
     const_cast<A*>(this)->b = 4; 
    } 

    mutable int a; 
    int b; 
}; 
+2

ここで* "安全でない" *は "インスタンスがconstの場合は未定義の動作を引き起こす"ことを意味します。 – user2079303

+6

Qtライブラリの 'const'-nessを打破するための技術的な回避策はお勧めしません。 –

+1

あなたが 'mutable'パス(OKです)を使う場合は、書き込みがスレッドセーフであることを確認してください(例えば上記の例では' a'にアトミックな書き込みを使用してください)、....または 'Item 16: Effective Modern C++からconstメンバー関数をスレッドセーフにする ' – marcinj