この概要では wxWidgets 3.0 と最後の安定リリースとの間の後方互換性のない変更について説明します。
互換性のない変更は次のカテゴリに分類できます:
wxWidgets 2.8 やそれ以前のバージョンで Unicode ビルドを使用していた場合、3.0 における API の変更点の詳細について wxWidgets における Unicode 対応 を参照してください。これまで正しかった多くの情報が 3.0 ではもはや当てはまりません。
例えば、(何を作成するのか分かりづらいことで) 悪名高い wxT()
マクロと _T()
マクロはもはや完全に不要になりました。基本的にはどのコードからも取り除くことができます。一方で、これらのマクロを残しておいても以前としてコンパイルできますし、正しく動作するため、特に害はありません。これらのマクロを削除してコードを綺麗にしたい場合だけ、マクロを削除する必要があります。また、wxChar
ももはや使用する必要がありません。ただし、繰り返しますが、標準の wchar_t
を直接使用できるとはいえ、wxChar
は引き続き動作します。
もっとも深刻な後方互換性のない変更は wxString::c_str() 関数の戻り値の型に関する変更です: 現在は単純な char*
や wchar_t*
の代わりに特別なプロキシオブジェクトを返却します。このため、Unicode 関連のコンパイルエラー で説明している通り、この戻り値を printf()
といった標準の可変引数関数に渡すことはもはやできません。wxPrintf()、wxLogMessage() など、すべての wxWidgets 関数は引き続き動作しますが、printf()
にこの戻り値を渡すとプログラムがクラッシュするでしょう。g++ など、非 POD オブジェクトを可変引数関数に渡すと警告を出すコンパイラを使用してコードをコンパイルし直すことを強く推奨します。
また、wxString::c_str() の戻り値の型を変更したことで、ナロー文字列とワイド文字列の両方を受け取るオーバーロード関数にこの戻り値を引き渡すとコンパイルエラーが発生するようになります。この場合はどちらの型を使用したいか選択する必要があります:
void OpenLogFile(const char *filename); void OpenLogFile(const wchar_t *filename); wxString s; OpenLogFile(s); // エラー: 曖昧 OpenLogFile(s.c_str()); // エラー: 曖昧 OpenLogFile(s.wx_str()); // OK: ビルドに応じて関数が呼ばれる OpenLogFile(s.mb_str()); // OK: 常にナロー文字列用のオーバーロードが呼ばれる OpenLogFile(s.wc_str()); // OK: 常にワイド文字列用のオーバーロードが呼ばれる
この問題の一般的な例は Microsoft Visual C++ 標準ライブラリにおける std::fstream
クラスのコンストラクタです。このクラスが必ず持たねばならない const
char
* のコンストラクタに加えて、ワイド文字列のファイル名を受け取るコンストラクタもこのクラスは提供しています。このため、次のようなコードは
#include <fstream> void MyFunc(const wxString& filename) { std::ifstream ifs(filename.c_str()); ... }
Microsoft Visual C++ を使用するとコンパイルされないため、mb_str() を使用するように変更する必要があります。(mb_str() は Unicode 文字を含むファイル名では動作しません。標準の C++ ライブラリではそのようなフィアル名に対応していないため、これらを取り扱える wxWidgets のクラスと関数を使用することを検討してください)
他の互換性のない変更は、いくつかの仮想関数を const
wxChar*
の代わりに wxString
を引数に取るように修正したことによるものです。この変更はナロー文字列とワイド文字列の両方を受け取るために行いました。関数を単純に呼び出しているのであれば問題になりませんが、これらの関数をオーバーライドしている場合、そのシグネチャの関数はもはや呼び出されなくなるため、継承クラスのシグネチャを変更する必要があります。繰り返しますが、この問題が発生しないようにする最良の方法は、関数のシグネチャの不一致を警告するコンパイラでリビルドすることです。(これには -Woverloaded-virtual
g++ オプションを使用できます。)
最後に、いくつかの構造体のフィールド、特に wxCmdLineEntryDesc::shortName
、longName
、 description
フィールドの型が const
wxChar*
から const
char*
に変更されました。そのため、それらのフィールドの初期化に wxT()
や _T()
を使用している場合、それらを取り除く必要があります。
もっとも簡単な解決策は enum 値を int へキャストすることです。
enum Colour { Red, Green, Blue }; wxConfig conf; conf.Write("MyFavouriteColour", Red); // エラー: 一致しない conf.Write("MyFavouriteColour", int(Red)); // OK
別の方法としては、独自の型用に wxToString() (と wxFromString()) をオーバーロードすることです。
wxString wxToString(Colour col) { return col == Red ?"R" : col == Green ?"G" : "B"; } bool wxFromString(const wxString& s, Colour* col) { if ( s.length() != 1 ) return false; switch ( s[0].GetValue() ) { case 'R': *col = Red; return true; case 'G': *col = Green; return true; case 'B': *col = Blue; return true; } return false; }
もちろん、これは望ましくない wxConfig の出力形式を変更します。