显式构造函数和重载

Posted

技术标签:

【中文标题】显式构造函数和重载【英文标题】:Explicit constructor and overloading 【发布时间】:2012-12-23 06:25:15 【问题描述】:
template<typename T>
class RAII

public:

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

    ~RAII() delete p_;

    T& operator*() const  return p_; 
    T* operator‐>() const return p_;
;

//Usage example:

      RAII<std::vector<int>> r(new std::vector<int>());
      std::cout<<r­‐>size()<<std::endl;
 // The std::vector<int> is automatically deallocated

大家好 :)

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

提前致谢。

【问题讨论】:

【参考方案1】:

第一件事:有两个错误: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­‐>size()<<std::endl;

r 在这里通过运算符重载伪装成std::vector&lt;int&gt;*。真正发生的是它被称为:

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

operator-&gt; 返回一个std::vector&lt;int&gt;*,所以第二个-&gt; 正在访问它并调用size() 方法。

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

运算符重载当然并不总是用来假装在做已经内置的东西。考虑ostreamoperator&lt;&lt;。它不是位移运算符,而是将数据放入流中。


更多信息:standard smart pointers/boost smart pointers/RAII/operator overloading。

哦,您的代码违反了通常遵循的rule-of-three(或rule of five in 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.

【讨论】:

那么运算符重载的目的是使用“r”作为 -> 运算符的指针还是作为 * 运算符的引用?我了解隐式构造函数和显式构造函数之间的区别,但我仍然不清楚这一行的目的:“显式 RAII(T* p = 0): p_(p)”。显式构造函数对 p 和 p_ 做了什么? @user1960649 对于您的第一个问题:是的,差不多。至于您的第二个问题:这称为初始化列表。它与显式构造函数无关。它只是意味着 p_ 被初始化为 p 的任何值。

以上是关于显式构造函数和重载的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在 PHP 中重载构造函数?

python0.16------构造函数/析构函数/self详解/重写/访问限制/对象属性和类属性/@property/运算符重载

C++复制构造函数和=号重载问题

显式移动构造函数?

为啥显式允许默认构造函数和具有 2 个或更多(非默认)参数的构造函数?

Java 构造函数和函数重载