3

const char*構築中に 2 つの文字列を連結し、後で初期化リストで結果 (連結された文字列) を使用する必要があるクラスがあります。

const char* SUFFIX = "suffix";

class widget {
public:
    widget(const char* prefix) : key(???), cls(key) { };

private:
    const char* key;
    const important_class cls;
}

widget("prefix_"); // key should be prefix_suffix

ユーザー指定のプレフィックスに追加したいグローバル (widgetの cpp)サフィックスがあります。const char*

どうやってするの?


ところで。について聞いたことがありstringます。私が使用できるなら、私はstringここでは尋ねません。const char*

4

7 に答える 7

3

を使用std::stringすると、問題が簡単なタスクになります。

const std::string SUFFIX = "suffix";

class widget {
public:
    widget(std::string const & prefix) 
           : key(prefix + SUFFIX), cls(key)
    { }       // ^^^^^^^^^^^^^^concatenation!

private:
    const std::string key;
    const important_class cls; 
}

widget("prefix_");

必要な場合はconst char*、callngkey.c_str()を返すことで取得できますconst char*。したがって、あなたの場合、c-string "prefix_suffix"が得られます。

また、正しく行った宣言の順序が重要であることに注意してください。その構造は に依存するため、後でcls宣言する必要があります。 keykey

于 2013-03-08T12:51:15.350 に答える
2

std::string中間値として使用:

const char* SUFFIX = "suffix";

class widget {
public:
    widget(const char* prefix) :
    intermediate(string(prefix) + suffix),
    key(intermediate.c_str()),
    cls(key) {
    }

private:
    const std::string intermediate;
    const char* key;
    const important_class cls;
}

widget("prefix_"); // key should be prefix_suffix

ここでのコードと異なるのは、プライベート メンバー変数intermediate.

std::stringオブジェクト は、intermediate連結を保持するために必要な動的メモリを管理します。例外、割り当て、コピーなどが発生した場合は、きれいにクリーンアップされます。

stringが変更されない限り、const char*返される byc_str()は有効なままです。intermediateisであるためconst、変更関数を呼び出すことはできないためcls、内部バッファーの使用に問題はありません。

于 2013-03-08T13:02:28.253 に答える
0

値の永続性などのニーズに応じて、2 つのオプションがあります。

1つ、次のように保存keyしますstd::string

const char* SUFFIX = "suffix";

class widget{
public:
  widget(const char* prefix) : key(std::string(prefix) + suffix), cls(key.c_str())
  {}

private:
  std::string key;
  const important_class cls;
};

2 つ目は、次のような静的初期化関数を使用することです。

const char* SUFFIX = "suffix";

class widget{
public:
  widget(const char* prefix) : key(concat_(prefix, suffix)), cls(key)
  {}

private:
  const char* key;
  const important_class cls;

  static const char* concat_(const char* a, const char* b)
  {
    std::string val(a);
    val += b;
    char* ret = new char[val.size() + 1];
    strcpy(ret, val.c_str());
    return val;
  }
};
于 2013-03-08T13:04:58.423 に答える
0

初期化リストでそれができるかどうかはわかりません。確かに、より多くの経験を持つ他のユーザーがそこで役立つ可能性があります...もちろん、これは明白に聞こえるかもしれませんが、 std::string を使用して次のように移動できます。

class widget 
{
    public:
    widget(const char* prefix) : key(prefix)
    { 
       string_key.append(suffix);
    };

    private:
    const char* key;
    std::string string_key;
};

もちろん、次のことができます。

class widget 
{
    public:
    widget(const char* prefix) : key(prefix)
    { 
       key.append(suffix);
    };

    private:
    std::string key;
};

「important_class」部分全体がありません。それはここで何を表していますか。あなたは何を達成しようとしていますか?

それが役立つことを願っています。

于 2013-03-08T12:55:16.667 に答える
0

あなたの質問は一見、理論的なクイズのように見えますが、STL を使用しない組み込みプラットフォームが存在する可能性があることを思い出しました。とにかく、昔ながらの C スタイルの関数である strlen、 strcpy、およびstrcat
に固執する必要があります。 クラスを使用しているため、演算子 new もコンパイラでサポートされていると思います。最終的なコードを記述する前に、文字列を連結するために必要な手順を次に示します。

const char* key;
key = new char[strlen(prefix) + strlen(SUFFIX) + 1];
strcpy(key, prefix);
strcat(key, SUFFIX);
...
delete [] key;

幸いなことに、strcpy と strcat の両方が宛先を返します。
コードは次のようになります。

#include <string.h>

class widget {
public:
  widget(const char* prefix)
    : key(strcat(strcpy(new char[strlen(prefix) + strlen(SUFFIX) + 1], prefix), SUFFIX))
    , cls(key) { };

private:
  const char* key;
  const important_class cls;
};

私はこのコードをデバッグしませんでしたが、うまくコンパイルできますが、かなり面倒に見えます... :)
デストラクタでバッファを解放することを忘れないでください。
幸運を!

于 2013-03-08T13:33:52.040 に答える
0

std::stringひもをまとめるために使用することをお勧めします。必要に応じて電話std::string::c_str()で取得することもできconst char*ます。も引数として取りますstd::string::appendconst char*または+-operator を使用します。

ここを参照してください。

于 2013-03-08T12:53:36.490 に答える