文字列データ用のクラス
概要
このページでは、Qt の文字列クラス、特に多数の文字列コンテナと、パフォーマンスが重要なコードでそれらを効率的に使用する方法について概要を説明します。
以下の効率的な使用方法に関する説明は、大量の文字列処理を含む、パフォーマンスが重要なコードに取り組んでいる経験豊富な開発者を対象としています。例としては、パーサーやテキストファイルジェネレータなどが挙げられます。一般的に、QString はあらゆる場面で使用でき、良好なパフォーマンスを発揮します。また、複数のエンコーディングを扱うためのAPI(例:QString::fromLatin1 ())も提供しています。多くのアプリケーション、特に文字列処理がパフォーマンスにほとんど影響を与えない場合、QString はシンプルで十分な解決策となります。一部のQt関数はQStringView を返します。必要に応じて、QStringView::toString ()を使用して、これをQString に変換することができます。
効果的なヒント
以下の3つのルールに従うことで、複雑さを過度に増すことなく、文字列処理を大幅に改善できます。これらのルールに従うことで、ほとんどの場合においてほぼ最適なパフォーマンスが得られます。最初の2つのルールは、文字列リテラルのエンコーディングとソースコード内でのマーク付けについて扱っています。3つ目のルールは、文字列の一部を使用する際のディープコピーについて扱っています。
- ASCII 文字のみを含むすべての文字列(例:ログメッセージ)は、Latin-1 でエンコードできます。string literal
"foo"_L1を使用してください。この接尾辞がない場合、ソースコード内の文字列リテラルは UTF-8 エンコードされているとみなされ、処理速度が低下します。一般的には、最も簡潔なエンコーディング(多くの場合、Latin-1)を使用するようにしてください。 - ユーザーに表示される文字列は通常、翻訳されるため、QObject::tr() 関数を介して渡されます。この関数は文字列リテラル(const char 配列)を受け取り、すべての UI 要素で要求される UTF-16 エンコーディングのQString を返します。翻訳インフラストラクチャを使用しない場合は、アプリケーション全体で UTF-16 エンコーディングを使用する必要があります。 UTF-16文字列リテラルを作成するには、文字列リテラル
u"foo"を使用するか、Qt固有のリテラルu"foo"_sを使用して、QString を直接作成してください。 - QString の一部を処理する際は、各部分を個別のQString オブジェクトにコピーする代わりに、QStringView オブジェクトを作成してください。これらはQStringView::toString()を使用してQString に戻すことができますが、可能な限りそうすることは避けてください。関数がQStringView を返す場合、可能であればこのクラスをそのまま使用し続けるのが最も効率的です。そのAPIは定数QString と似ています。
効率的な使用法
文字列クラスを効率的に使用するには、次の3つの概念を理解する必要があります:
- エンコーディング
- 所有型および非所有型のコンテナ
- リテラル
エンコーディング
エンコーディングに関して、Qt は UTF-16、UTF-8、Latin-1 (ISO 8859-1)、および US-ASCII (Latin-1 と UTF-8 の共通部分) を何らかの形でサポートしています。
- Latin-1 は、1 文字につき 1 バイトを使用する文字エンコーディングであり、最も効率的である反面、制限も多いエンコーディングです。
- UTF-8 は、1 文字あたり 1 から 4 バイトを使用してすべての文字をエンコードする可変長文字エンコーディングです。US-ASCII との下位互換性があり、ソースコードや類似のファイルで一般的に使用されるエンコーディングです。Qt では、ソースコードは UTF-8 でエンコードされているものと想定しています。
- UTF-16は、1文字あたり2バイトまたは4バイトを使用する可変長エンコーディングです。これは、Qtにおいてユーザーに表示されるテキストの一般的なエンコーディングです。
詳細については、QtにおけるUnicodeのサポートに関する情報を参照してください。
その他のエンコーディングは、QString::fromUcs4() のような単一の関数、またはQStringConverter クラスの形でサポートされています。さらに、Qt には、バイナリデータの格納に最適な、エンコーディングに依存しないデータコンテナQByteArray が用意されています。QAnyStringView は、基になる文字列のエンコーディングを追跡するため、サポートされているあらゆるエンコーディング規格の文字列に対するビューを保持することができます。
エンコーディング間の変換は処理負荷が高いため、可能な限り避けるべきです。一方で、特に文字列リテラルにおいて、よりコンパクトなエンコーディングを使用することでバイナリサイズを削減でき、パフォーマンスの向上につながります。 文字列リテラルを Latin-1 で表現できる場合、たとえある時点で UTF-16 に変換される必要があったとしても、これらの相反する要素の間で良好なバランスを保つことができます。Latin-1 文字列を `QString` に変換する必要がある場合、その処理は比較的効率的に行われます。
機能
文字列クラスは、サポートする機能によってさらに区別することができます。主な区別の一つは、データを所有し、したがって制御しているか、それとも単に他の場所に保持されているデータを参照しているかという点です。前者は「所有型コンテナ」、後者は「非所有型コンテナ」または「ビュー」と呼ばれます。 非所有型コンテナは通常、データの先頭へのポインタとそのサイズを記録するだけであるため、軽量かつ低コストですが、データが利用可能な状態にある間のみ有効です。 所有型文字列は、データを格納するメモリを管理し、コンテナの存続期間を通じてデータが利用可能であることを保証しますが、その生成と破棄にはメモリの割り当てと解放にかかるコストが発生します。ビューは通常、所有型文字列の機能の一部のみをサポートしており、基になるデータを変更する機能はありません。
その結果、文字列ビューは、たとえばパーサー内など、より大きな文字列の一部を表すのに特に適しているのに対し、所有型文字列は、クラスのメンバなど、永続的な保存に適しています。 関数が、例えば断片を結合して構築した文字列を返す場合は、所有型文字列を返す必要があります。しかし、関数が永続的に保存された文字列の一部を返す場合は、通常、ビューの方が適しています。
Qt の所有コンテナはデータを暗黙的に共有することに注意してください。つまり、参照カウントのため参照渡しよりもわずかに効率は劣りますが、大きなコンテナを値渡しで渡したり返したりすることも効率的です。 Qt クラスの暗黙的なデータ共有メカニズムを利用したい場合は、文字列を所有コンテナとして、あるいはその参照として渡す必要があります。ビューへの変換および逆変換を行うと、常にデータの追加コピーが作成されます。
最後に、Qt には単一の文字、文字列のリスト、および文字列マッチング用のクラスが用意されています。これらのクラスは、一部の例外を除き、Qt でサポートされているほとんどのエンコーディング規格で使用可能です。 より高レベルの機能は、QLocale やQTextBoundaryFinder などの特化されたクラスによって提供されます。これらの高レベルクラスは通常、QString およびそのUTF-16エンコーディングに依存しています。一部のクラスはテンプレートであり、利用可能なすべての文字列クラスで動作します。
リテラル
C++ 標準では、コンパイル時に文字列を作成するための文字列リテラルが提供されています。 文字列リテラルには、言語によって定義されたものと、Qt によって定義されたもの(いわゆるユーザー定義リテラル)があります。C++ で定義された文字列リテラルは二重引用符で囲まれ、その内容をコンパイラがどのように解釈すべきかを示す接頭辞を付けることができます。Qt の場合、UTF-16 文字列リテラルu"foo" が最も重要です。 これはコンパイル時にUTF-16でエンコードされた文字列を作成するため、実行時に他のエンコーディングから変換する必要がなくなります。QStringView はこれを使って簡単かつ効率的に構築できるため、QStringView 引数(あるいはその結果としてQAnyStringView )を受け入れる関数に渡すことができます。
ユーザー定義リテラルは、C++で定義されたものと同じ形式ですが、閉じ引用符の後に接尾辞が追加されます。エンコーディングは接頭辞によって決定されますが、結果として得られるリテラルは、あるユーザー定義型のオブジェクトを構築するために使用されます。 したがって、Qt は独自の文字列型の一部に対してこれらを定義しています。QString に対しては `u"foo"_s `、QLatin1StringView に対しては `"foo"_L1 `、QByteArray に対しては `u"foo"_ba ` です。これらは `StringLiterals Namespace` を使用して提供されます。単純な C++ 文字列リテラル `"foo" ` は UTF-8 として解釈されるため、`QString ` への変換、ひいては UTF-16 への変換には大きなオーバーヘッドが生じます。 プレーンASCIIの文字列リテラルがある場合は、"foo"_L1 を使用してそれをLatin-1として解釈することで、前述のさまざまなメリットを得ることができます。
基本的な文字列クラス
以下の表は、さまざまなテキストエンコーディング規格に対応する基本的な文字列クラスの概要を示しています。
| エンコーディング | C++ 文字列リテラル | Qt のユーザー定義リテラル | C++ 文字 | Qt 文字 | 所有権を持つ文字列 | 非所有文字列 |
|---|---|---|---|---|---|---|
| Latin-1 | - | ""_L1 | - | QLatin1Char | - | QLatin1StringView |
| UTF-8 | u8"" | - | char8_t | - | - | QUtf8StringView |
| UTF-16 | u"" | u""_s | char16_t | QChar | QString | QStringView |
| バイナリ/なし | - | ""_ba | std::byte | - | QByteArray | QByteArrayView |
| フレキシブル | 任意 | - | - | - | - | QAnyStringView |
欠落しているエントリの一部は、C++の組み込み型や標準ライブラリの型で代用可能です。所有権を持つLatin-1またはUTF-8エンコードされた文字列は、std::string 、あるいは任意の8ビットchar 配列で表すことができます。QStringView は、一部のプラットフォームにおけるstd::u16stringやstd::wstringなど、任意の16ビット文字配列も参照できます。
これらの型の一部に対して、QStringList やQByteArrayView といった専用のリストに加え、マッチャーであるQLatin1StringMatcher やQByteArrayMatcher も提供されています。これらのマッチャーには、コンパイル時に生成される静的バージョンであるQStaticLatin1StringMatcher やQStaticByteArrayMatcher もあります。
さらに注目すべき点として:
- QStringLiteral は、
u"foo"_sと同一であり、StringLiterals Namespace なしで利用可能なマクロです。できれば、最新の文字列リテラルを使用することをお勧めします。 - QLatin1String はQLatin1StringView の別名であり、下位互換性のために存在します。これは所有型文字列ではなく、将来のリリースで削除される可能性があります。
- QAnyStringView は、サポートされている3つのエンコーディングのいずれかを持つ文字列のビューを提供します。エンコーディングはデータへの参照とともに保存されます。このクラスは、幅広い種類の文字列タイプやエンコーディングを受け入れるインターフェースを作成するのに適しています。他のクラスとは対照的に、QAnyStringView に対して直接処理は行われません。 処理は、それぞれのエンコーディングで、基になるQLatin1StringView 、QUtf8StringView 、またはQStringView に対して行われます。このクラスを引数として受け取る独自の関数内で同様の処理を行うには、QAnyStringView::visit() を使用してください。
- UTF-8 エンコードされたソースコードファイル内で、非 ASCII 文字を含む `QLatin1StringView ` を単純に構築することは難しく、特別な処理が必要となります。詳細は `QLatin1StringView ` のドキュメントを参照してください。
- QStringRef は、QString の一部への参照であり、下位互換性のために Qt5Compat モジュールで提供されています。これはQStringView に置き換える必要があります。
文字列関連のハイレベルクラス
追加機能を提供するより高レベルのクラスの多くは、主に `QString `(したがって UTF-16)を扱います。これらは以下の通りです:
- QRegularExpression、QRegularExpressionMatch 、およびQRegularExpressionMatchIterator (パターンマッチングや正規表現を扱うためのもの)。
- QLocale ユーザーの言語や文化に適した方法で、数値やデータを文字列に変換したり、文字列から数値やデータに戻したりするためのクラス。
- QCollator および `QCollatorSortKey `:ユーザーの言語、文字体系、または地域に基づいて文字列を比較します。
- QTextBoundaryFinder Unicodeの規則に従って、組版用にテキストを分割します。
QStringBuilder+演算子による文字列連結のパフォーマンスを大幅に向上させる内部クラス。詳細については、 のドキュメントを参照してください。QString
一部のクラスはテンプレートであるか、柔軟な API を備えており、さまざまな文字列クラスと連携します。これらは
- QTextStream QIODevice 、 、またはQByteArray QString
- QStringTokenizer 文字列を分割する
どの文字列クラスを使用すべきか?
文字列クラスの使用に関する一般的な指針は次のとおりです。
- コピーやメモリ割り当ては避け、
- エンコーディングの変換を避け、
- 最もコンパクトなエンコーディングを選択する。
Qtには、メモリ割り当てを回避するための多くの機能が用意されています。ほとんどのQtコンテナは、データの「暗黙的共有(Implicit Sharing)」を採用しています。暗黙的共有が機能するためには、同じクラスの連続したチェーンが存在する必要があります。QString からQStringView へ変換し、再び逆変換を行うと、データを共有しない2つのQStrings が生成されてしまいます。 したがって、関数はデータをQString として渡す必要があります(値でも参照でも構いません)。暗黙的なデータ共有では、文字列の一部を抽出することはできません。長い文字列の一部を使用するには、明示的なデータ共有形式である文字列ビューを利用してください。
エンコーディング間の変換は、特定のエンコーディングに統一することで削減できます。たとえば、UTF-8で受信したデータは、他のエンコーディングへの変換が必要ない場合は、UTF-8のまま保存・処理するのが最善です。同じエンコーディングの文字列間の比較は最も高速であり、他のほとんどの操作についても同様です。 特定のエンコーディングの文字列を頻繁に比較したり、他のエンコーディングに変換したりする場合は、一度変換して保存しておくことが有益な場合があります。一部の操作では、さまざまな文字列型やエンコーディングを受け入れるための多くのオーバーロード(またはQAnyStringView オーバーロード)が用意されており、同じエンコーディングを使用することが不可能な場合、パフォーマンスを最適化するための第二の選択肢としてこれらを利用すべきです。 関数を呼び出す前の明示的なエンコーディング変換は、他に選択肢がない場合の最終手段とすべきです。Latin-1は非常に単純なエンコーディングであり、Latin-1と他のエンコーディング間の操作は、同一エンコーディング間の操作とほぼ同等の効率で実行されます。
エンコーディングを決定する他の制約がない場合は、最も効率的なエンコーディング(効率の高い順に Latin-1、UTF-8、UTF-16)を選択すべきです。エラー処理やロギングには、通常QLatin1StringView で十分です。Qt におけるユーザーに表示される文字列は常にQString 型であり、したがって UTF-16 でエンコードされています。 したがって、ユーザーに表示される文字列のライフサイクル全体を通じて、QStrings 、QStringViews 、およびQStringLiterals を使用するのが最も効果的です。QObject::tr()関数は、正しいエンコーディングと型を提供します。エンコーディングが問題にならない場合(例えばバイナリデータの保存など)や、エンコーディングが不明な場合は、QByteArray を使用すべきです。
API作成用のStringクラス
メンバ変数
メンバー変数は、ほぼすべてのケースにおいて、所有型である必要があります。ビューは、参照される所有文字列のライフタイムがオブジェクトのライフタイムを上回ることが保証されている場合にのみ、メンバー変数として使用できます。
関数の引数
関数の引数は、ほとんどの場合、適切なエンコーディングの文字列ビューであるべきです。複数のエンコーディングをサポートするには、QAnyStringView をパラメータとして使用でき、内部でQAnyStringView::visit()を使用してエンコーディングごとの関数に分岐させることができます。関数が単一のエンコーディングに限定されている場合は、QLatin1StringView 、QUtf8StringView 、QStringView 、またはQByteArrayView を使用すべきです。
関数が引数を所有型文字列に保存する場合(通常はセッター関数)、Qtの暗黙的なデータ共有機能を活用するために、関数の引数として同じ所有型文字列を使用するのが最も効率的です。所有型文字列は、const の参照として渡すことができます。 複数の所有型および非所有型の文字列型を使用して関数をオーバーロードすると、オーバーロードの曖昧性が生じる可能性があるため、避けるべきです。Qtにおける所有型文字列は、非所有型またはQAnyStringView に自動的に変換されます。
戻り値
一時的な文字列は、所有型文字列(通常はQString )として返さなければなりません。返される文字列がコンパイル時に判明している場合は、u"foo"_s を使用して、コンパイル時にQString 構造体を生成してください。 既存の所有型文字列(例:QString )が関数から完全に返される場合(例:ゲッター関数)、参照渡しで返すのが最も効率的です。将来的に一時的な文字列を返せるようにするため、値渡しで返すことも可能です。Qt XMLにおける暗黙の共有(implicit sharing)の仕組みにより、値渡しによる返却時に割り当てやコピーによるパフォーマンスへの影響を回避できます。
既存の文字列の一部は、適切なエンコーディングの文字列ビューを使用して効率的に返すことができます。例として、QStringView を返すQRegularExpressionMatch::capturedView()を参照してください。
API を使用するための String クラス
Qt API を効率的に使用するには、関数の引数型を一致させるよう努めるべきです。選択肢が限られている場合、Qt はさまざまな変換を行います。所有型文字列は暗黙的に非所有型文字列に変換され、非所有型文字列は対応する所有型文字列を作成できます。例として、QStringView::toString() を参照してください。 エンコーディングの変換は多くの場合暗黙的に行われますが、可能であればこれを避けるべきです。UTF-8からの意図しない暗黙的な変換を防ぐには、QT_NO_CAST_FROM_ASCII マクロを有効にしてください。
実行時に文字列を組み立ててから関数に渡す必要がある場合は、所有型文字列が必要となるため、QString を使用する必要があります。関数の引数がQStringView またはQAnyStringView の場合、暗黙的に変換されます。
文字列がコンパイル時に判明している場合は、最適化の余地があります。 関数が `QString` を受け入れる場合は、u"foo"_s またはQStringLiteral マクロを使用して生成する必要があります。関数が `QStringView` を期待する場合は、通常の UTF-16 文字列リテラルu"foo" を使用して生成するのが最適です。`QLatin1StringView ` が期待される場合は、"foo"_L1 を使用して生成します。両方の選択肢がある場合(例えば、関数が `QAnyStringView` を期待する場合など)、最も厳密なエンコーディング(通常は Latin-1)を使用してください。
文字列関連のすべてのクラスの一覧
QString APIの読み取り専用サブセットを用いた、Latin-1、UTF-8、またはUTF-16文字列の統一的なビュー | |
バイト配列 | |
バイト配列の一覧 | |
バイト配列内で高速にマッチングできる一連のバイトを保持します | |
QByteArray API の読み取り専用サブセットを備えたバイト配列のビュー | |
16 ビットの Unicode 文字 | |
ローカライズされた照合順序アルゴリズムに従って文字列を比較します | |
文字列の照合を高速化するために使用可能 | |
8 ビット ASCII/Latin-1 文字 | |
Latin-1 テキスト内の部分文字列検索を最適化 | |
US-ASCII/Latin-1 エンコードされた文字列リテラルをラップする薄いラッパー | |
さまざまな言語における数値とその文字列表現間の変換を行います | |
正規表現を用いたパターンマッチング | |
QRegularExpression オブジェクトと文字列とのマッチング結果 | |
QRegularExpression オブジェクトによる文字列のグローバルマッチング結果に対するイテレータ | |
QByteArrayMatcher のコンパイル時バージョン | |
QLatin1StringMatcherのコンパイル時バージョン | |
Unicode 文字列 | |
テキストのエンコードおよびデコードのための基底クラス | |
テキスト用の状態ベースのデコーダ | |
テキスト用の状態ベースのエンコーダ | |
文字列のリスト | |
Unicode文字列内で高速に照合可能な一連の文字を保持する | |
QStringのサブストリングをラップした軽量ラッパー | |
指定された区切り文字に沿って文字列をトークンに分割する | |
QString APIの読み取り専用サブセットを備えた、UTF-16文字列に対する統一的なビュー | |
文字列内のUnicodeテキスト境界を検出する方法 | |
テキストの読み書きを行うための便利なインターフェース | |
QString APIの読み取り専用サブセットを用いた、UTF-8文字列に対する統一的なビュー |
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.