0
template<typename T>
class RAII
{
public:

    explicit RAII( T* p = 0 ): p_(p){}

    ~RAII() {delete p_;}

    T& operator*() const { return p_;} 
    T* operator‐&gt;() const{ return p_;}
};

//Usage example:
{
      RAII<std::vector<int>> r(new std::vector<int>());
      std::cout<<r­‐&gt;size()<<std::endl;
} // The std::vector<int> is automatically deallocated

嗨,大家好 :)

我的问题:在这种特定情况下,显式构造函数和两个运算符重载的目的是什么,以及它们在用法示例中是如何使用的?

提前致谢。

4

1 回答 1

0

第一件事:有两个错误: p_ 没有声明,返回operator*应该是return *p_.


无论如何,显式是所以构造函数不能被隐式调用。

考虑一下:

class Example {
public:
    int x;
    Example(int x) : x(x) {}
};

function ex(const Example& e) {
    std::cout << e.x;
}

int main() {
    ex(5);
    return 0;
}

你期望这个编译吗?确实如此。它输出 5。原因是 Example 是隐式构造的。基本上ex(5)就是默默的变成了ex(Example(5))。将构造函数标记为显式会禁止这种行为。如果您向构造函数添加显式,这将是编译时错误。


至于运算符重载,这里有一个基本的“智能”指针。(如果您不能使用具有标准化编译器的编译器,我可能会使用 C++11 中的标准编译器之一。)

运算符重载允许对象以特定方式对对象作出反应。在这种情况下,运算符重载允许类假装是它所包含的同一类型的指针。

RAII<std::vector<int>> r(new std::vector<int>());
std::cout<<r­‐&gt;size()<<std::endl;

r在这里假装是一个std::vector<int>*via 运算符重载。真正发生的是它被称为:

(r­.operator->())->size()

operator->返回 a std::vector<int>*,所以第二个->是访问它并调用该size()方法。

您可能熟悉的另一个运算符重载示例是 std::vector's operator[]operator[]返回对元素的引用。

运算符重载当然并不总是用来假装在做已经内置的事情。考虑一下ostreamoperator<<它不是位移运算符,而是将数据放入流中。


更多信息:标准智能指针/提升智能指针/ RAII /运算符重载

哦,您的代码违反了非常普遍遵守的三规则(或C++11 中的五规则)。实际上,如果制作了副本,您的类将双重删除指针。

RAII<int> p(new int)
RAII<int> q = p;
//when q's destructor runs, bad bad things will happen since p's destructor already deleted the int.
于 2013-01-09T08:51:28.163 回答