我正在阅读Stroustrup的C++(1997年第3版),以了解他如何实现RAII,在365页上,我发现了这一点:

class File_ptr{
    FILE* p;
public:
    File_ptr(const char* n, const char* a){p = fopen(n, a);}
    File_ptr(FILE* pp) { p = pp; }
    ~File_ptr() {fclose(p);}
    operator FILE* () {return p;}
};

构造函数和析构函数的实现是显而易见的,并且符合RAII习惯用法,但是我不明白他为什么使用operator FILE* () {return p;}

这将导致以以下方式使用File_ptr:
FILE* p = File_ptr("myfile.txt", "r");

结果为封闭的p,在这种情况下在语义上是不合适的。同样,如果将File_ptr用作RAII,则该运算符将允许它像示例中那样被滥用。还是我错过了什么?

最佳答案

似乎这是不可避免的邪恶代价。一旦您希望从您喜欢的RAII类中提取FILE*的方法,就可以将其滥用。它是operator FILE*()还是FILE* getRawPtr()方法,或者其他任何方法,都可以在临时对象上调用它,从而使结果在返回后立即无效。

但是,在C++ 11中,可以通过禁止对临时对象的调用来使此操作更加安全,如下所示:

operator FILE* () & { return p; }
// Note this -----^

Morwenn在评论中提供了有关其工作方式的有用链接:What is "rvalue reference for *this"?

关于c++ - Stroustrup的RAII和强制转换运算符FILE *()=矛盾?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22068277/

10-11 23:01
查看更多