文字列データ用クラス

概要

このページでは、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" を、直接QString を作成するには Qt 固有のリテラルu"foo"_s を使用してください。
  • 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~4バイトでエンコードします。US-ASCII との後方互換性があり、ソースコードや同様のファイルでは一般的なエンコーディングです。Qt では、ソースコードは UTF-8 でエンコードされていると仮定しています。
  • UTF-16 は可変長エンコーディングで、1 文字あたり 2 バイトまたは 4 バイトを使用します。UTF-16 は、1 文字あたり 2 バイトまたは 4 バイトを使用する可変長のエンコーディングで、Qt ではユーザーによって公開されるテキストの一般的なエンコーディングです。

詳しくは、Qt の Unicode サポートに関する情報を参照してください。

その他のエンコーディングは、QString::fromUcs4() のような関数やQStringConverter クラスでサポートされています。さらに、Qt はバイナリデータの保存に適した、エンコーディングにとらわれないデータ用コンテナQByteArray を提供しています。QAnyStringView は、基礎となる文字列のエンコーディングを追跡するため、サポートされているどのエンコーディング規格の文字列も表示することができます。

エンコーディング間の変換にはコストがかかるため、可能であれば避けてください。一方、よりコンパクトなエンコーディング、特に文字列リテラルは、バイナリサイズを小さくすることができ、パフォーマンスを向上させることができます。文字列リテラルがLatin-1で表現できる場合、ある時点でUTF-16に変換しなければならないとしても、これらの競合する要因の間の良い妥協点を管理します。Latin-1文字列をQString 、比較的効率的に変換することができます。

機能性

文字列クラスは、サポートする機能によってさらに区別することができます。大きな違いの1つは、そのクラスがデータを所有し、制御しているのか、それとも単に他の場所にあるデータを参照しているのか、という点です。前者を所有コンテナ、後者を非所有コンテナまたはビューと呼ぶ。非所有コンテナ型は通常、データの開始位置とそのサイズへのポインタを記録するだけなので、軽量で安価だが、データが利用可能である限り有効である。所有する文字列は、そのデータを格納するメモリを管理し、コンテナの寿命が尽きるまでデータが利用可能であることを保証しますが、その作成と破棄にはメモリの割り当てと解放のコストが発生します。ビューは通常、所有する文字列の機能のサブセットをサポートし、基礎となるデータを変更する可能性はありません。

その結果、文字列ビューは、パーサなどのより大きな文字列の一部を表すのに特に適しており、一方、所有文字列は、クラスのメンバのような永続的なストレージに適しています。関数が、フラグメントを組み合わせるなどして作成した文字列を返す場合は、所有文字列を返す必要があります。

Qt の所有コンテナは暗黙のうちにデータを共有するため、大きなコンテナを値で渡したり返したりすることも効率的です。Qt クラスの暗黙のデータ共有メカニズムを利用したい場合は、文字列をコンテナとして渡すか、コンテナへの参照として渡す必要があります。ビューに変換して戻すと、常にデータのコピーが追加で作成されます。

最後に、Qtは単一文字、文字列のリスト、文字列マッチャーのクラスを提供しています。これらのクラスは、いくつかの例外を除いて、Qt でサポートされているほとんどのエンコーディング規格で使用できます。より高度な機能は、QLocaleQTextBoundaryFinder のような特殊なクラスによって提供されます。これらの高度なクラスは通常、QString とその UTF-16 エンコーディングに依存しています。いくつかのクラスはテンプレートになっており、利用可能なすべての文字列クラスで動作します。

リテラル

C++標準では、コンパイル時に文字列を作成するための文字列リテラルを提供しています。文字列リテラルには、言語によって定義されたものと、Qt によって定義されたもの、いわゆるユーザー定義リテラルがあります。C++で定義された文字列リテラルは二重引用符で囲まれ、コンパイラがその内容をどのように解釈するかを示す接頭辞を持つことができます。Qt では、UTF-16 文字列リテラルu"foo" が最も重要です。コンパイル時にUTF-16でエンコードされた文字列を作成するため、実行時に他のエンコーディングから変換する手間が省けます。QStringView は、1つの文字列から簡単かつ効率的に作成できるため、QStringView 引数を受け取る関数に渡すことができます(結果として、QAnyStringView )。

ユーザー定義リテラルは、C++で定義されたものと同じ形式を持ちますが、閉じ引用符の後に接尾辞が追加されます。エンコーディングは接頭辞によって決定されたままですが、結果として得られるリテラルは、何らかのユーザー定義型のオブジェクトを構築するために使用されます。Qt では、独自の文字列型としてQStringu"foo"_sQLatin1StringView"foo"_L1QByteArrayu"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-8u8""-char8_t--QUtf8StringView
UTF-16u""u""_schar16_tQCharQStringQStringView
バイナリ/なし-""_bastd::バイト-QByteArrayQByteArrayView
フレキシブル柔軟----QAnyStringView

不足している項目のいくつかは、組み込み型や標準ライブラリC++型で代用することができます:所有する Latin-1 または UTF-8 でエンコードされた文字列は、std::string または任意の 8 ビット配列char とすることができます。QStringView は、一部のプラットフォームでは std::u16string や std::wstring のような任意の 16 ビット文字配列を参照することもできます。

Qt は、QStringListQByteArrayView といった特殊なリストや、QLatin1StringMatcherQByteArrayMatcher といったマッチャーも提供しています。マッチャーには、コンパイル時に作成される静的バージョン(QStaticLatin1StringMatcherQStaticByteArrayMatcher )もあります。

さらに注目すべき点がある:

  • QStringLiteral は、 と同じマクロで、 なしで利用できます。できれば、最新の文字列リテラルを使うべきです。u"foo"_s StringLiterals Namespace
  • QLatin1String は の同義語で、後方互換性のために存在します。所有文字列ではないので、将来のリリースでは削除されるかもしれません。QLatin1StringView
  • QAnyStringView は、サポートされている3つのエンコーディングのいずれかを持つ文字列のビューを提供します。エンコーディングは、データへの参照と一緒に格納されます。このクラスは、さまざまな文字列型やエンコーディングを扱うインターフェースの作成に適しています。他のクラスとは対照的に、 に対する処理は直接行われません。処理は、それぞれのエンコーディングの 、 、 。このクラスを引数に取る独自の関数で同じ処理を行うには、 () を使用してください。QAnyStringView QLatin1StringView QUtf8StringView QStringView QAnyStringView::visit
  • 非ASCII文字を含むQLatin1StringView は、UTF-8でエンコードされたソース・コード・ファイルでは単純には構築できず、特別な処理が必要です。QLatin1StringView のドキュメントを参照してください。
  • QStringRef は、後方互換性のために Qt5Compat モジュールで利用可能な の一部への参照です。これは で置き換える必要があります。QString QStringView

追加機能を提供する高レベルのクラスは、主にQString と UTF-16 で動作します。これらは以下のとおりです:

  • QRegularExpression QRegularExpressionMatch と は、パターン・マッチと正規表現を扱います。QRegularExpressionMatchIterator
  • QLocale ユーザーの言語や文化に適した方法で数値やデータを文字列に変換する。
  • QCollator および 、ユーザーの言語、スクリプト、または領土に関して文字列を比較します。QCollatorSortKey
  • QTextBoundaryFinder Unicodeルールに従って、組版準備の整ったテキストを分割する。
  • QStringBuilderまた、+ 演算子を使った文字列連結のパフォーマンスを大幅に向上させる内部クラスもあります。QString ドキュメントを参照してください。

いくつかのクラスはテンプレートであったり、柔軟なAPIを持ち、様々な文字列クラスで動作します。これらは

どの文字列クラスを使うべきか?

文字列クラスを使用する際の一般的なガイダンスは以下の通りです:

  • コピーとメモリ確保を避ける、
  • エンコーディングの変換を避ける。
  • 最もコンパクトなエンコーディングを選択する。

Qtはメモリ割り当てを避けるために多くの機能を提供しています。ほとんどのQtコンテナは、データの暗黙的共有を採用しています。暗黙的な共有が機能するためには、同じクラスが途切れることなく連鎖している必要があります。QString からQStringView に変換して戻すと、データを共有しない2つのQStrings ができてしまいます。したがって、関数はデータをQString として渡す必要があります(値でも参照でもかまいません)。暗黙のデータ共有では、文字列の一部を取り出すことはできません。より長い文字列の一部を使用するには、明示的なデータ共有である文字列ビューを使用します。

特定のエンコーディングにこだわることで、エンコーディング間の変換を減らすことができます。例えばUTF-8で受け取ったデータは、他のエンコーディングへの変換が必要ない場合、UTF-8で保存・処理するのが最適です。同じエンコーディングの文字列同士の比較は最速であり、他のほとんどの処理も同様である。あるエンコーディングの文字列を頻繁に比較したり、他のエンコーディングに変換したりするのであれば、一度変換して保存した方が有益かもしれません。操作の中には、様々な文字列型やエンコーディングを受け付けるオーバーロード(またはQAnyStringView オーバーロード)を多数提供しているものがあり、同じエンコーディングを使用することが不可能な場合は、パフォーマンスを最適化するために2番目の選択肢とすべきです。関数を呼び出す前の明示的なエンコーディング変換は、他の選択肢がない場合の最後の手段であるべきです。Latin-1は非常に単純なエンコーディングであり、Latin-1と他のエンコーディング間の演算は、同じエンコーディング間の演算とほぼ同じ効率です。

他にエンコーディングを決定する制約がない場合は、最も効率的なエンコーディング(最も効率的なLatin-1、UTF-8、UTF-16の順)を選択する必要があります。エラー処理とロギングについては、通常はQLatin1StringView で十分です。Qt では、ユーザーから見える文字列は常にQString 型で、UTF-16 エンコードされています。そのため、QStringsQStringViewsQStringLiterals を使用するのが最も効果的です。QObject::tr ()関数は、正しいエンコーディングと型を提供します。QByteArray は、バイナリデータを格納する場合など、エンコーディングが重要でない場合や、エンコーディングが不明な場合に使用します。

API作成用文字列クラス

最適なAPIのための文字列クラス

メンバ変数

メンバ変数は、ほぼすべての場合において所有型であるべきです。ビューは、参照される所有文字列の寿命がオブジェクトの寿命を超えることが保証されている場合にのみ、メンバ変数として使用することができます。

関数引数

関数の引数は、ほとんどの場合、適切なエンコーディングの文字列ビューであるべきです。QAnyStringView をパラメータとして使用することで、複数のエンコーディングをサポートすることができます。また、QAnyStringView::visit() を内部で使用することで、エンコーディングごとの関数に分岐することができます。関数が単一のエンコーディングに限定されている場合は、QLatin1StringViewQUtf8StringViewQStringView またはQByteArrayView を使用する必要があります。

関数が引数を所有文字列(通常はセッター関数)に保存する場合、Qtの暗黙のデータ共有機能を利用するために、関数の引数として同じ所有文字列を使用するのが最も効率的です。所有文字列は、const 参照として渡すことができます。複数の所有文字列型と非所有文字列型で関数をオーバーロードすることは、オーバーロードの曖昧さにつながるので避けるべきです。Qt の所有文字列型は、自動的に非所有文字列型またはQAnyStringView に変換されます。

戻り値

QString一時的な文字列は、所有文字列として返さなければなりません。返される文字列がコンパイル時に既知である場合は、u"foo"_s を使用して、QString 構造体をコンパイル時に構築します。既存の所有文字列(たとえばQString )が関数(たとえばゲッター関数)から完全に返される場合、参照で返すのが最も効率的です。また、将来的に一時的なものを返せるように、値で返すこともできます。Qt では暗黙的な共有を使用することで、値で返す場合のアロケーションやコピーによるパフォーマンスへの影響を回避しています。

例えば、QStringView を返すQRegularExpressionMatch::capturedView() を参照してください。

API を使用するための文字列クラス

関数を呼び出すための文字列クラス

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 を使用します。

QAnyStringView

QString API の読み取り専用サブセットを使用した、Latin-1、UTF-8、UTF-16 文字列の統一ビュー。

QByteArray

バイト配列

QByteArrayList

バイト配列のリスト

QByteArrayMatcher

バイト配列で素早くマッチできるバイト列を保持します。

QByteArrayView

QByteArray API の読み取り専用サブセットを使用してバイト配列を表示します。

QChar

16 ビット Unicode 文字

QCollator

ローカライズされた照合アルゴリズムに従って文字列を比較します。

QCollatorSortKey

文字列の照合を高速化するために使用可能

QLatin1Char

8 ビット ASCII/Latin-1 文字

QLatin1StringMatcher

Latin-1 テキストの部分文字列の最適化検索

QLatin1StringView

US-ASCII/Latin-1エンコードされた文字列リテラルの薄いラッパー

QLocale

様々な言語における数値とその文字列表現の変換

QRegularExpression

正規表現を使ったパターンマッチ

QRegularExpressionMatch

文字列に対するQRegularExpressionのマッチング結果

QRegularExpressionMatchIterator

QRegularExpressionオブジェクトの文字列に対するグローバルマッチの結果のイテレータ

QStaticByteArrayMatcher

QByteArrayMatcher のコンパイル時バージョン

QStaticLatin1StringMatcher

QLatin1StringMatcher のコンパイル時バージョン

QString

Unicode 文字列

QStringConverter

テキストのエンコードとデコードのための基本クラス

QStringDecoder

テキストのステートベース・デコーダ

QStringEncoder

テキストのステートベース・エンコーダ

QStringList

文字列のリスト

QStringMatcher

Unicode文字列の中で素早くマッチできる文字のシーケンスを保持します。

QStringRef

QString 部分文字列の薄いラッパー

QStringTokenizer

与えられたセパレータに沿って文字列をトークンに分割

QStringView

QString API の読み取り専用サブセットによる UTF-16 文字列の統一ビュー

QTextBoundaryFinder

文字列内の Unicode テキスト境界を見つける方法

QTextStream

テキストの読み書きに便利なインタフェース

QUtf8StringView

QString API の読み取り専用サブセットによる UTF-8 文字列の統一ビュー

© 2025 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.