0

我刚刚对一个项目进行了大规模重构,以添加一个基类来代替现在所说的基类的派生类(因为我想要这个类的更多“类型”)。

我的问题是,一些实用函数将原始类 A 的引用作为 shared_ptr ,因此函数声明如下所示:

void UtilityClass::func(shared_ptr<A> &a);

但是现在我有了新的基类 B 并且 A 是从 B 派生的(以及从 B 派生的新类 C),当我尝试传递 A 或 C 的实例时出现编译时错误到现在声明为的函数:

void UtilityClass::func(shared_ptr<B> &b);

如果我尝试通过:

shared_ptr<A> a;
utilclass.func(a);

我收到一个编译时错误,说(释义):

无法将参数 1 从 'std::shared_ptr<_Ty>' 转换为 'std::shared_ptr<_Ty>'

但我不确定我还能如何解决这个问题,func() 将 A、B 或 C 实例添加到 shared_ptr 值的 std::vector 中。

谢谢你的时间。

编辑:我还有另一个函数,它接受一个引用,以便它可以为它分配一个新的 B 实例,然后返回它。

4

4 回答 4

6

问题是您通过非const引用传递,这意味着您需要参数类型完全匹配。

更改函数以通过值或const引用获取指针;然后可以将隐式转换(例如shared_ptr<Derived>to shared_ptr<Base>)应用于参数。

于 2013-08-01T13:19:15.233 回答
2

以下工作没有任何问题,并且是受支持的方案:

#include <tchar.h>
#include <memory> 
#include <iostream>

class Foo { };

class Bar : public Foo { };

int _tmain() 
{
  std::shared_ptr<Bar> b(new Bar());

  std::cout << b.use_count() <<std::endl;

  std::shared_ptr<Foo> f(b);

  std::cout << b.use_count() <<std::endl;
  std::cout << f.use_count() <<std::endl;

  return 0;
}

如果类是派生的,则不会出现问题。

于 2013-08-01T11:22:29.677 回答
1

更改shared_ptr<A> a;shared_ptr<B> a; 您仍然可以为其分配更多派生类型的指针,但通过基类实现多态性。

于 2013-08-01T11:05:09.200 回答
0

这有效:

class A {
public:
    virtual ~A() {};
    virtual void print() {
        puts("A prints");
    }
};
class B: public A {
public:
    void print() {
        puts("B prints");
    }
};


void func(std::shared_ptr<A> a) {
    a->print();
}


int main()
{
    std::shared_ptr<A> b_1(new B()); // can hold B*
    std::shared_ptr<B> b_2(new B());

    // both next function calls print "B prints"
    func(b_1);
    func(b_2); // can accept std::shared_ptr<B>
}
于 2016-05-04T03:15:43.250 回答