我写了一个智能指针类。当我将它传递给向量时,它会在编译时显示一些错误消息。但在删除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)));
}
答案 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
。