1

私の String クラスは、演算子 char* オーバーロードを提供して、文字列を C 関数に渡すことができるようにします。

残念ながら、私の同僚がうっかりバグを発見してしまいました。

彼は効果的に次のコードを持っていました。

StringT str;
// Some code.
delete str;

このような将来のバグが発生するのを防ぐために、delete が文字列オブジェクトを char* にキャストするのを防ぐ方法はありますか? std::stringは、char 演算子のオーバーロードを提供しないことでこの問題を回避しますが、理想的には、オーバーロードを保持したまま、その削除が機能しないようにしたいと考えています。

4

5 に答える 5

8

はい。宣言する (ただし、定義しない!) ことにより、2 つの暗黙のキャストを提供し operator char const volatile*ます。StringTC 文字列関数に渡す場合、オーバーロードの解決では引き続き元のoperator char const*(完全一致) が選択されます。しかし、delete str;今では曖昧になります。

宣言は非公開にすることができるので、それが何らかの形で選択されると、コンパイル時エラーになります。意図されたあいまいさは、オーバーロード解決の前に発生します。これは、オーバーロードが何らかの形で選択されるprivate非常にまれなケースをキャッチするのに役立ちます。volatile

于 2010-01-26T10:00:07.310 に答える
5

delete が文字列オブジェクトを char* にキャストするのを防ぐ方法はありますか ...?

はい: 暗黙のキャスト演算子は避けてください。それは、少なくとも 10 年前から説かれてきました。それを信じて、より幸せな人生を送ってください。

于 2010-01-26T09:30:34.287 に答える
4

信じられないかもしれませんが、std::string が暗黙的な変換を提供しないのには理由があります。c_str() 関数は、あなたを苛立たせるためだけに作成されたものではありません。暗黙の変換を提供すると、あいまいさと痛みの世界に自分自身が開かれます。

于 2010-01-26T09:34:53.253 に答える
0

物議を醸す意見の時間:誰かがこの「バグ」に苦しむコードを書いた場合、彼らは噛まれるに値します。

あなたの質問を言い換えると:

人々が私の銃器を使って自分の足を撃たないようにするにはどうすればよいですか?

できません。@sbiの意見に同意せず、過負荷は問題ないと言います。これが誰かのコードに問題を引き起こす場合、それは誰かがC ++を知らないので、それをコーディングするべきではないからです。

言語を十分に理解していない人がdelete、ポインタではないことを知らない人があなたのクラスを悪用する可能性があるかどうかよりも、心配すべき大きな問題があります。

警告:私はC ++に比較的慣れていないので、グリズリしたベテランの恐怖を見たことがありません。特に悪いあいまいさのサンプルが私の邪悪な方法を私に納得させる可能性があります。しかし、これはそうではありません。

于 2010-01-26T09:37:03.813 に答える
0
struct Dummy {};
class StringT {
public:
    // ........
    operator char*() { /*...*/ }
    operator const char*() const { /*...*/ }

    operator const Dummy* () const { return 0; }
    operator Dummy* () { return 0; }
};

/// ...
void g(const char * ) { /*...*/ }

int main() {

    StringT str;
    g(str); // OK
    delete str; //error C2440: 'delete' : cannot convert from 'StringT' to 'void *'
    return 0;
}
于 2010-01-26T10:25:45.353 に答える