我想了解从Foo<Derived>
到Foo<Base>
之类的转换。举个例子,如果我有下面的代码段(长,不好意思):从Foo转换<Derived>到Foo <Base>
#include <iostream>
#include <memory>
#include <vector>
class Base
{
public:
virtual void print() const = 0;
virtual void print() = 0;
};
class Derived : public Base
{
public:
virtual void print() const override { std::cout << "Derived::print const\n"; }
virtual void print() override { std::cout << "Derived::print\n"; }
};
template <typename R>
class BasePtr
{
public:
BasePtr() : ptr_(std::make_shared<R>())
{
}
void print() const
{
ptr_->print();
}
private:
std::shared_ptr<R> ptr_;
};
/* Takes const shared ptr */
void takesConstSharedPtr(const std::shared_ptr<Base>& base)
{
base->print();
}
void takesConstSharedPtrConst(const std::shared_ptr<const Base>& base)
{
base->print();
}
/* Takes non-const shared ptr */
void takesSharedPtr(std::shared_ptr<Base>& base)
{
base->print();
}
void takesSharedPtrConst(std::shared_ptr<const Base>& base)
{
base->print();
}
/* Takes base ptr class */
void takesBase(BasePtr<Base>& base)
{
base.print();
}
void takesBaseConst(BasePtr<const Base>& base)
{
base.print();
}
/* Takes const base ptr class */
void takesConstBase(const BasePtr<Base>& base)
{
base.print();
}
void takesConstBaseConst(const BasePtr<const Base>& base)
{
base.print();
}
int main()
{
std::shared_ptr<Derived> ptr = std::make_shared<Derived>();
BasePtr<Derived> basePtr;
// Works!
takesConstSharedPtr(ptr);
takesConstSharedPtrConst(ptr);
// Does not works...
takesSharedPtr(ptr);
takesSharedPtrConst(ptr);
takesConstBase(basePtr);
takesConstBaseConst(basePtr);
takesBase(basePtr);
takesConstBase(basePtr);
}
我得到了前两个电话在主函数中的最后6调用编译错误,但没有编译错误。如果我注释掉在过去的6个电话,可以编译成功,并得到预期的输出:
Derived::print
Derived::print const
这到底是怎么回事?为什么shared_ptr<Derived>
能够转换为const shared_ptr<Base>
和const shared_ptr<const Base>
,但不是非常量版本?另外,如何编写BasePtr
以便能够模仿shared_ptr
的行为?
编译错误,我得到如下:
'void takesBase(BasePtr<Base> &)': cannot convert argument 1 from 'BasePtr<Derived>' to 'BasePtr<Base> &'
及其组合。
您在调用ptr_(std :: make_shared())时调用派生函数的原因是什么构造函数? –