4

我有:

class A : public std::enable_shared_from_this<A>
{...};

class B : public A
{...}; 

void doCoolStuff(std::weak_ptr<A> obj)
{...}

void doCoolStuff(std::weak_ptr<B> obj)
{
 ...
 doCoolStuff(std::static_pointer_cast<A>(obj.lock())); (1)
}

然后在 B 函数中:

void B::doReallyCoolStuff()
{
 doCoolStuff(std::static_pointer_cast<B>(shared_from_this())); (2)
}

所以问题是:

  1. 编译器错误:error C2440: 'static_cast' : cannot convert from 'B *const ' to 'A *'
  2. 编译器错误:error C2668: ambiguous call to overloaded function

我不明白如何解决它们,因为:

  1. 我认为它与 shared_from_this 有某种联系,因为这是const 指针。但是如果没有 const_cast,我不知道如何处理这种情况。
  2. 我不知道函数是否可以被不同类型的弱指针重载。

搭建环境:MSVS 2013 express

请帮忙。谢谢

4

2 回答 2

6

至于问题(2),你当然可以像这样重载。但问题是您使用 type 调用函数std::shared_ptr<B>。这需要隐式转换为 a std::weak_ptr,并且可以同时转换为std::weak_ptr<A>and std::weak_ptr<B>。这两者都是由内部的隐式转换构造函数实现的std::weak_ptr,这意味着它们都没有比另一个更好。因此模棱两可。

要解决此问题,您可以显式指定类型:

void B::doReallyCoolStuff()
{
    doCoolStuff(std::weak_ptr<B>(std::static_pointer_cast<B>(shared_from_this())));
}

活生生的例子

或者,您可以提供doCoolStufftake的重载std::shared_ptr

正如上面的实时示例所示,我无法重现问题 (1)。

于 2014-09-17T08:42:49.790 回答
2

您可能想查看函数的参数。

如果函数需要在返回后将指针保留在某处,则函数只需要接受智能指针。否则函数应该接受引用或普通指针。

根据 Herb Sutter 在Back to the Basics 中的说法!现代 C++ 风格的要点 - Herb Sutter - CppCon 2014接受智能指针(按值或按引用)的函数是一种反模式,除非这些函数需要存储、更改或放弃引用:

  • 不要再使用拥有 raw *、new 或 delete,除非在低级数据结构的实现细节中很少使用。

  • 一定要使用非拥有的原始 * 和 &,特别是对于参数。

  • 不要复制/分配引用计数的智能指针,包括按值传递或循环,除非你真的想要它们表达的语义:改变对象生命周期。

于 2014-09-17T08:49:00.213 回答