1

new operator以下のコードでは、最初の行でオブジェクトの状態が既に変更されているため、この実装は例外セーフではないため、関数呼び出しによって例外が発生する可能性があることを著者は指摘しています。

String &String::operator =( const char *str ) {
    // state is changed
    delete [] s_;                                        

    if( !str ) str = "";

    // exception might occur because of new operator
    s_ = strcpy( new char[ strlen(str)+1 ], str );

    return *this;
}

読んでいるときに、Cライブラリ関数はC++で例外をスローするのだろうかと思いましたか? C には例外がないことはわかっていますが、C++ コンパイラを使用しているため、例外がある可能性があります。

では、c 標準 lib 関数を例外安全な関数呼び出しと見なすことができますか?

ありがとうございました。

ところで、記録のために、上記の関数を実装する正しい方法 (例外セーフ) を以下に示します。

String &String::operator =( const char *str ) {
    if( !str ) str = "";
    char *tmp = strcpy( new char[ strlen(str)+1 ], str );
    delete [] s_;
    s_ = tmp;
    return *this;
}
4

3 に答える 3

5

読んでいるときに、Cライブラリ関数はC++で例外をスローするのだろうかと思いましたか?

関数を正しく使用している場合はそうではありません。どうして彼らは?それは下位互換性を完全に壊します。

ただし、誤って使用すると、未定義の動作が発生します。その場合、コンパイラは、例外のスローを含め、必要なことを何でも実行できます。

たとえば、C++ 言語標準に従って未定義の動作を示す次のプログラムを取り上げます。

#include <iostream>
#include <string.h>

int main()
{
    try
    {
        strcpy(nullptr, nullptr);
    }
    catch (...)
    {
        std::cerr << "exception\n";
    }
}

次のように構造化例外処理を使用して、Visual C++ 2013 でコンパイルします。

cl /nologo /Za /EHa /W4 stackoverflow.cpp

プログラムの結果:

exception
于 2015-03-08T12:10:20.757 に答える
0

いいえ - C++ コンパイラでコンパイルしたからといって、例外がスローされるわけではありません。C は例外をサポートしていないため、C プログラムはいかなる種類の例外もスローできません。

于 2015-03-08T11:32:57.383 に答える