gpt4 book ai didi

c++ - 从类型的右值初始化类型的非常量引用无效

转载 作者:行者123 更新时间:2023-11-30 03:43:12 24 4
gpt4 key购买 nike

我正在根据更有效的 c++ 问题 28 智能指针编写一些代码,如下所示。但是,它无法编译:

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)
^

这两个更改中的任何一个都有效:

  1. 在operator SmartPointer()的实现中,创建一个对象并返回:

    智能指针 a(ptr_);

    返回一个;

  2. 或者,将拷贝构造函数的参数设为const

    SmartPointer(const SmartPointer& 其他)

    并注释该行

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

最佳答案

那是因为你的复制构造函数有一个非常量引用参数,因此不能接受一个临时的。因此

return SmartPointer<X>(y);

不会工作。 return 关键字的参数是临时的,需要复制,所以这里设计就崩溃了。

由于您使用的是 C++11,因此可以通过引入移动构造函数(和移动赋值)来解决此问题。

您还可以将参数设置为 const 并将 ptr_ 成员指定为 mutable。这将允许您从临时指针和 const 智能指针进行复制,但代价是实际改变它们。

关于c++ - 从类型的右值初始化类型的非常量引用无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36269776/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com