我正在编写一些基于问题28的更有效的c ++智能指针的代码,如下所示。但是,它无法编译:
main.cpp: In instantiation of 'SmartPointer<T>::operator SmartPointer<U>() [with U = MusicProduct; T = Cassette]':
main.cpp:99:17: required from here
main.cpp:48:39: error: invalid initialization of non-const reference of type 'SmartPointer<MusicProduct>&' from an rvalue of type 'SmartPointer<MusicProduct>'
return SmartPointer<U> (ptr_);
^
main.cpp:16:9: note: initializing argument 1 of 'SmartPointer<T>::SmartPointer(SmartPointer<T>&) [with T = MusicProduct]'
SmartPointer(SmartPointer<T>& other)
^
这两项改变都有效:
在运算符SmartPointer()的实现中,创建一个对象并返回:
SmartPointer a(ptr _);
返回a;
或者,将复制构造函数的参数设为const
SmartPointer(const SmartPointer&amp; other)
并评论该行
other.ptr_ = nullptr;
为什么其中一种解决方案有效?感谢。
#include <iostream>
template <typename T>
class SmartPointer
{
public:
SmartPointer(T* ptr) : ptr_(ptr) {}
~SmartPointer()
{
if (ptr_)
{
delete ptr_;
}
}
SmartPointer(SmartPointer<T>& other)
{
ptr_ = other.ptr_;
other.ptr_ = nullptr;
}
SmartPointer<T>& operator = (SmartPointer<T>& other)
{
if (this == &other)
{
return *this;
}
if (ptr_)
{
delete ptr_;
}
ptr_ = other.ptr_;
other.ptr_ = nullptr;
return *this;
}
template <typename U>
operator SmartPointer<U> ()
{
// it works
//SmartPointer<U> a(ptr_);
//return a;
// error
return SmartPointer<U> (ptr_);
}
T& operator * () const
{
return *ptr_;
}
T* operator -> () const
{
return ptr_;
}
private:
T* ptr_ = nullptr;
};
class MusicProduct
{
public:
MusicProduct(const std::string& name) : name_(name) {}
virtual ~MusicProduct() {}
virtual void Play() const = 0;
virtual void ShowName() const
{
std::cout << name_ << std::endl;
}
private:
std::string name_;
};
class Cassette : public MusicProduct
{
public:
Cassette(const std::string& name) : MusicProduct(name) {}
void Play () const
{
std::cout << "play cassette" << std::endl;
}
};
void CallPlay(const SmartPointer<MusicProduct>& sp)
{
sp->Play();
}
int main()
{
SmartPointer<Cassette> a(new Cassette("Zhang"));
a->ShowName();
CallPlay(a);
return 0;
}
答案 0 :(得分:2)
那是因为你的copy ctor有一个非const引用参数,因此无法接受临时参数。因此
return SmartPointer<X>(y);
不起作用。 return关键字的参数是临时的,需要复制,因此这里的设计会中断。
由于您使用的是C ++ 11,因此可以通过引入移动构造函数(并移动赋值)来解决此问题。
您还可以创建参数const
并将ptr_
成员指定为mutable
。这将允许你从temporaries和const智能指针复制,但实际上是为了改变它们的价格。