问题1>以下代码为什么不起作用?
问题2>设计它的正确方法是什么?
#include <iostream>
#include <vector>
#include "boost/shared_ptr.hpp"
using namespace std;
class BaseClass
{};
class SubClass : public BaseClass
{};
int main()
{
std::vector<boost::shared_ptr<SubClass> > vecSubClassShared;
boost::shared_ptr<SubClass> sub1(new SubClass);
vecSubClassShared.push_back(sub1);
// Error 1 error C2440: 'initializing' : cannot convert from 'std::vector<_Ty>' to 'const std::vector<_Ty> &`
const std::vector<boost::shared_ptr<BaseClass> >& vecBaseShared = vecSubClassShared;
}
答案 0 :(得分:4)
在C ++编译器的视图中,shared_ptr<BaseClass>
和shared_ptr<DerivedClass>
是不同的,不相关的类型。虽然编译器知道,正常的指针可以从Derived*
转换为Base*
,但它不知道在概念上应该同样适用于shared_ptr
,因为它不知道“智能指针” “像指针一样。
同样适用于矢量或模板一般:模板的两个实例是两个不同的类,它们之间没有关系(如果没有明确设计)。因此,编译器看到vector<Something>
绑定到vector<SomethingElse>
的引用,这些引用不是相关类型,因此引用绑定失败。
但即使类型以某种方式相关,绑定也会失败:
long l = 5;
int& ir = l; //ERROR
答案 1 :(得分:1)
shared_ptr<BaseClass>
和shared_ptr<SubClass>
是不同的,不相关的类型,因此一个向量无法为另一个向量添加别名,因为无法保证它们的对象布局相同。 / p>
这意味着,例如将const std::vector<boost::shared_ptr<BaseClass> >&
传递给您必须构建所需类型的临时向量的函数。但是,您可以使用共享指针别名在不增加共享指针的引用计数的情况下执行此操作:
#include <vector>
#include <memory>
struct B {};
struct D: public B {};
template<typename T, typename U>
std::vector<std::shared_ptr<T>> shared_vector_static_cast(
const std::vector<std::shared_ptr<U>> &v)
{
std::vector<std::shared_ptr<T>> w;
for (const std::shared_ptr<U> &p: v)
w.push_back(std::shared_ptr<T>(std::shared_ptr<void>(), p.get()));
return w;
}
int main() {
std::vector<std::shared_ptr<D>> v{std::make_shared<D>()};
const std::vector<std::shared_ptr<B>> &w = shared_vector_static_cast<B>(v);
}