Std :: stringを拡張して、カスタム関数ビルドをCustomStringという文字列クラスに書き込む必要があるというニーズを満たしました。
コンストラクターを定義しました:
class CustomString : public std::string {
public:
explicit CustomString(void);
explicit CustomString(const std::string& str);
explicit CustomString(const CustomString& customString);
//assignment operator
CustomString& operator=(const CustomString& customString);
... };
3番目のコンストラクター(コピーコンストラクター)と代入演算子。その定義は次のとおりです。
CustomString::CustomString(const CustomString& customString):
std::string(static_cast<std::string>(customString))
{}
CustomString& CustomString::operator=(const CustomString& customString){
this->assign(static_cast<std::string>(customString));
return *this;
}
まず、これは「明示的」であるためです。つまり、別のCustomStringオブジェクトに割り当てるには明示的なキャストが必要です。それは割り当てについて不平を言っています。
CustomString s = CustomString("test");
キャストが明示的に必要な場所が正確にわからない。
コピーコンストラクターが明示的でない場合、コードは正常に機能しますが、「適切なキャストを推測する」のではなく、明示的な定義を知り、実装したいと思います。
明示的なコピーコンストラクターは、コピーコンストラクターが暗黙的に呼び出されないことを意味します。これは、式で発生することです。
CustomString s = CustomString("test");
この式は文字通り、次のことを意味します。const char*
をとるコンストラクターを使用して一時的なCustomString
を作成します。 CustomString
のコピーコンストラクターを暗黙的に呼び出して、その一時的なものからs
にコピーします。
これで、コードが正しい場合(つまり、コピーコンストラクターが明示的でない場合)、コンパイラーは一時的なものの作成を回避し、文字列リテラルを使用してs
を直接作成することでコピーを削除します。ただし、コンパイラは、構築が実行可能であり、そこで失敗することを確認する必要があります。
コピーコンストラクタを明示的に呼び出すことができます。
CustomString s( CustomString("test") );
ただし、一時的なものは完全に避け、const char*
を使用してs
を作成することをお勧めします。
CustomString s( "test" );
とにかくコンパイラが行うことはどれですか...
Std :: stringには仮想デストラクタがないため、std :: stringからの派生は安全ではありません。あなたの質問に関して-あなたのコピーコンストラクタは、次のような使用法を可能にするために、明示的であってはなりません:
CustomString s = "test";
また、コピーコンストラクターを明示的に宣言する必要がないので、なぜそれを宣言したいのかわかりません。明示的なコピーコンストラクターは、CustomStringオブジェクトを次のように宣言した場合にのみ機能します。
CustomString s(CustomString("test"));