私は このコード 期待どおりに機能します:
#define MAX_PARAM_NAME_LEN 32
const char* GetName()
{
return "Test text";
}
int main()
{
char name[MAX_PARAM_NAME_LEN];
strcpy(name, GetName());
cout << "result: " << name << endl;
}
結果をchar *
に保存したい場合(使用しているフレームワーク内の一部の関数は入力としてchar *
のみを使用するため)、strcpy
を使用せずに(実用性とコードの可読性、そして学習も)、どうすればよいですか? const
を維持すると、これはうまく機能します。
const char* name;
name = GetName();
しかし、私はまだconst
を持っています。
char*
を使用しようとしています:
char* name;
name = GetName();
invalid conversion from 'const char*' to 'char*'
を取得します。この種の改宗の最良の習慣は何ですか?
_return "Test text";
_は、読み取り専用文字列リテラルへのポインタを返します。
_char*
_を入力として受け取る関数を使用していて、_const char*
_(読み取り専用の文字列リテラルなど)がある場合は、文字列のディープコピーを提供する必要があります。その_const char*
_からそのような関数まで。
そうしないと、関数が読み取り専用の文字列を変更しようとすると、実行時に未定義の動作が発生するリスクがあります。
あなたが現在持っているものは十分です。 _std::string
_で作業できないと仮定します。 (can _std::string
_で作業する場合andすべてのフレームワーク関数が_const char*
_入力を受け取る場合は、使用するコードをリファクタリングすることをお勧めします_std::string
_、およびその文字列クラスのc_str()
メソッドの出力をフレームワーク関数に渡します。)
最後に、フレームワーク関数の一部に_char*
_が必要な場合は、いつでも小さなアダプタークラスを作成できます。
_class Adapter
{
public:
Adapter(const& Adapter) = delete; /*don't try to copy me please*/
Adapter& operator=(const Adapter& ) = delete; /*don't try to copy me please*/
Adapter(const char* s) : m_s(::strdup(s))
{
}
~Adapter() /*free memory on destruction*/
{
::free(m_s); /*use free to release strdup memory*/
}
operator char*() /*implicit cast to char* */
{
return m_s;
}
private:
char* m_s;
};
_
次に、関数void foo(char* c)
の場合、foo(Adapter("Hello"/*or any const char* */));
を呼び出すことができ、匿名の一時関数に埋め込まれている_char*
_を使用して、foo
を自由に実行できます。このクラスを拡張して、コンストラクターを_char*
_に移動することもできます。その場合、ポインターの浅いコピーのみが取得されます(デストラクタはメモリを削除しません)。
この種の変換の最良の習慣は、コード全体で_std::string
_を使用することです。使用しているフレームワークは入力として_const char*
_を受け取るため、_std::string
_の呼び出しの結果をいつでも渡すことができます: c_str()
_std::string GetName() {
return "Test text";
}
int main() {
std::string name = GetName();
int res = external_framework_function(name.c_str());
cout << "result: " << res << " for " << name << endl;
}
_
次善の策は、コードで_const char*
_を使用することです。
_const char* name = GetName();
_
使用しているフレームワークは_const char*
_を取るので、ここでも問題ありません。
非constポインターが必要な場合は、文字列をコピーする方法はありません。あなたはあなたのためにそれをする関数を作ることができます、しかしあなたはあなたがそれから得たコピーを解放する責任があります:
_char* copy(const char* orig) {
char *res = new char[strlen(orig)+1];
strcpy(res, orig);
return res;
}
...
char *name = copy(GetName());
...
delete[] name;
_