2016-04-05 7 views
0

C++コンパイラでは、QStringLiteralsをC++ヘッダファイル内の#defineにすることができます。私は複数回QStringLiteral("bar")を入力するために避けることができるように、foo.hを含んで異なるの.cppファイルにQStringLiteralsをヘッダファイルに#defineできますか?

// foo.h 
#ifndef FOO_H 
#define FOO_H 

#define BAR QStringLiteral("bar") 

#endif 

目標は、(コピー)を使用することですBAR:ような何か。

しかし:

  • が、それは安全ですか? (QStringLiteralがクラッシュする可能性があると聞きました)
  • 効率的ですか? (つまり、1回だけ割り当てられた文字列ですか?)
+4

マクロを定義するだけでは実際には何も起こりませんし、コンパイラが見るコードには影響しません。マクロの使用方法はすべてです。 –

+0

@JoachimPileborg:目的は、 'foo.h 'を含むさまざまな.cppファイルで' BAR'を使用することです。 – eang

+4

はテキスト置換を定義するだけです。したがって、原則としてあなたが望むものを定義することができます。それは安全ですか?可能であれば、マクロは避けてください。あなたが望むものを、はるかに良く、より安全にすることができます。あなたは実際に何を達成したいのですか?この '#define'の目的は何ですか? – user463035818

答えて

5

これをしないでください。ご質問については

  • が、それは安全ですか?質問は QStringLiteralがクラッシュすることがある理由で、その答えは、ライブラリやプラグインのアンロードと関係してい

(私はQStringLiteralがクラッシュにつながることを聞きました)。 QStringLiteralは静的なペイロード(QString自身のデータと実際の文字列)を参照するQStringを作成します。このQStringがライブラリAで作成され、ライブラリBに渡され、ライブラリAがアンロードされた場合、Bには危険なダングリングポインタが残されます。 Qtがここでできることは何もありません。

  • 効率的ですか? (すなわち、一度だけ割り当てられた文字列である?)

すべてではない:

  1. あなたはどこでもあなたがそれを使用登場する文字列リテラルデータで終わります。これにより、データサイズが爆発したり、複数のTUに渡って同じ文字列リテラルデータをマージするためにリンカーに負荷をかけたりする可能性があります。
  2. QStringLiteralはラムダ式に展開されるため(コンパイラに指定されています)、マクロが表示されるたびにラムダ式のコードを解析して生成するようコンパイラに指示します。
  3. 各ラムダはオブジェクト同じTUであっても、複数のマクロ展開を簡単にコンパイラでマージすることはできません。最近のオプティマイザは、同じバイナリコードを折り畳み始めました。

ソリューション:ヘッダファイル内

// foo.h 
#ifndef FOO_H 
#define FOO_H 

QString bar(); 

#endif 

そして

// foo.cpp 
#include "foo.h" 
QString bar() { 
    return QStringLiteral("bar"); 
} 
1

私は#defineしことができますQStringLiterals:ライン機能のうちを書くのか?

他の回答で説明されているように、ただしできません。

もう1つの方法は、グローバルな名前空間の汚染を避けるために、プレフィックスを区別してグローバル文字列定数を使用することです。あなたはまた、名前空間にそれらを置くことができます:あなたは初期化順序心配している場合は

// bar.h 
#pragma once 
#include <QString> 

extern const QString kBar; // approach 1 
namespace K { 
    extern const QString bar; // approach 2 
} 

// bar.cpp 
#include "bar.h" 

const QString kBar { QStringLiteral("bar"); } 
const QString K::bar { QStringLiteral("bar"); } 

// main.cpp 
#include "bar.h" 
int main() { 
    qDebug() << kBar << K::bar; 
} 

を、その後、単にあなたがmain()を入力する前の値が未定義れていることを前提とし、 main()は、これらの定数に依存するすべてのインスタンスを明示的にインスタンス化します。とにかくそれをコード化するべきでしょうから、それは実際には問題ではありません。

関連する問題