当我将构造函数声明为显式时编译错误

时间:2013-03-09 12:27:57

标签: c++

我写了一个智能指针类。当我将它传递给向量时,它会在编译时显示一些错误消息。但在删除explict声明后,它可以正常工作。什么是错误?

explicit shared_ptr(const shared_ptr<T>& sp)
  

没有用于调用shared_ptr<int>::shared_ptr(const shared_ptr<int> &)

的匹配函数
 #include <iostream>
    #include <vector>
    using namespace std;




    template<class T>
    class shared_ptr {
    private:
      struct ptr {
        T* ptr;
        size_t count;
        void release() {
          if(-- count == 0) {
            delete ptr;
            delete this;
          }
        }
      };
    private:
      ptr* _ptr;
    public:
      explicit shared_ptr(T* p):
        _ptr(new ptr) {
        _ptr->ptr = p;
        _ptr->count = 1;
      }
      explicit shared_ptr(const shared_ptr<T>& sp):
      //explicit shared_ptr(const shared_ptr& sp):
        _ptr(sp._ptr) {
        ++ _ptr->count;
      }
      shared_ptr<T>& operator=(const shared_ptr<T>& sp) {
        _ptr->release();
        _ptr = sp._ptr;
        ++ _ptr->count;
        return *this;
      }

      shared_ptr<T>& operator=(T* p) {
        _ptr->release();
        _ptr = new ptr;
        _ptr->count = 1;
        _ptr->ptr = p;
      }

      T* get() {
           return _ptr->ptr;
      }

      T& operator*() {
        return *(_ptr->ptr);
      }

      T* operator->() {
          return _ptr->ptr;
      }


      ~shared_ptr() {
        _ptr->release();
      }


    };



    int main() {
        vector<shared_ptr<int> > vec;
        vec.push_back(shared_ptr<int>(new int(10)));
    }

1 个答案:

答案 0 :(得分:1)

声明为explicit的构造函数只能在显式调用它时使用。在这一行:

vec.push_back(shared_ptr<int>(new int(10)));

您正在将值传递给vec,在标准库的 C ++ 03 实现中,最终将复制到正在进行的向量中复制初始化,例如:

_Tp __x_copy = __x;

此处对复制构造函数的调用是隐式,但您的构造函数标记为explicit。因此,错误。

请注意,使用C ++ 03编译器或使用-std=c++03标志进行编译时出现错误,因为在C ++ 11中调用{{1}带有rvalue参数的函数(就像你实例化的临时函数)最终会通过对复制构造函数的显式调用来创建值。

因此,我假设您正在使用C ++ 03编译器。

通常,push_back()构造函数是构造函数,它接受一个参数不是复制构造函数,以避免笨拙的隐式转换(实际上,在C ++ 11中,{{1对于带有多个参数的构造函数也是有意义的,因为通过括号初始化列表进行复制初始化)。

复制构造函数通常声明为explicit