0

我写了一个智能指针类。当我将它传递给向量时,它会在编译时显示一些错误消息。但是在我删除显式声明后,它就起作用了。有什么错误?

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)));
    }
4

1 回答 1

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 中,push_back()使用右值参数调用函数(如您正在实例化的临时函数)最终会创建通过显式调用复制构造函数来实现值。

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

通常,explicit构造函数是接受一个参数不是复制构造函数的构造函数,以避免尴尬的隐式转换(实际上,在 C++11 中,explicit对于接受多个参数的构造函数也是有意义的,因为复制初始化通过大括号初始化器列表)。

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

于 2013-03-09T12:43:04.737 回答