c++ - 多态性和 shared_ptr 通过引用传递

标签 c++ c++11 polymorphism pass-by-reference

我尝试将具有多态类的 shared_ptr 发送给函数。 我的目标是找到发送我的 shared_ptr 的最佳方式 不增加 ref_count。

编辑:我不搜索我的 shared_ptr 被替换的解决方案,因为我想调用 shared_ptr.reset() 例如。

目前,void doGenericTemplate(std::shared_ptr<CLASS>& ptr)是我想要的结果,但我更喜欢程序中的单个函数。

  1. 你有其他解决方案吗?

此外,我不明白为什么函数void doGeneric(std::shared_ptr<Base>& ptr)不编译(等效于没有 shared_ptr 的工作正常:请检查完整代码中的 doClassic)。

  1. 你有解释吗?

谢谢!

部分代码

#include <iostream>
#include <memory>

class Base
{
    public:
        Base() = default;
        virtual ~Base() = default;
        virtual void run() = 0;
};

class Derived1: public Base
{
    public:
        Derived1() = default;
        virtual ~Derived1() = default;
        void run()
        {
            std::cout << "  Derived1";
        }
};

class Derived2: public Base
{
    public:
        Derived2() = default;
        virtual ~Derived2() = default;
        void run()
        {
            std::cout << "  Derived2";
        }
};

// This function works but increase count
void doGenericCopy(std::shared_ptr<Base> ptr)
{
    ptr->run();
    std::cout << "  Ref count: " << ptr.use_count() << std::endl;
}

// This function works without increase count = OK !
void doSpecificD1(std::shared_ptr<Derived1>& ptr)
{
    ptr->run();
    std::cout << "  Ref count: " << ptr.use_count() << std::endl;
}

// Compilation error = FAILED !
void doGeneric(std::shared_ptr<Base>& ptr)
{
    ptr->run();
    std::cout << "  Ref count: " << ptr.use_count() << std::endl;
}

// Working fine for all Derivate = OK !
template<typename CLASS>
void doGenericTemplate(std::shared_ptr<CLASS>& ptr)
{
    ptr->run();
    std::cout << "  Ref count: " << ptr.use_count() << std::endl;
}

int main()
{
    auto d1 = std::make_shared<Derived1>();
    auto d2 = std::make_shared<Derived2>();

    std::cout << "With copy: " << std::endl;
    doGenericCopy(d1);
    doGenericCopy(d2);

    std::cout << "Specific: " << std::endl;
    doSpecificD1(d1);

    std::cout << "Template: " << std::endl;
    doGenericTemplate(d1);
    doGenericTemplate(d2);

    // Compilation issue
    //doGeneric(d1);
}

完整代码

https://ideone.com/ZL0v7z

结论

目前在c++中,shared_ptr在语言中还没有专门的工具来使用模板内部类的多态性。

最好的方法是重构我的代码并避免管理 shared_ptr (ref_count, reset)。

谢谢大家!

最佳答案

  1. Do you have another solution ?

通过引用或 const 引用传递对象而不是 shared_ptr .

void doGeneric(Base& r)
{
    r.run();
}

首先 - 这明确表明您没有在某处存储或缓存指针。其次 - 你要避免像你在这里展示的那样含糊不清。

  1. Do you have an explain ?

传递 shared_ptr<Derived>函数导致隐式转换为 shared_ptr<Base> .这个新shared_ptr<Base>是临时的,所以不能转换为 shared_ptr<Base> & .这种隐式转换会增加引用计数,即使您可以传递它也是如此。

关于c++ - 多态性和 shared_ptr 通过引用传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48649877/

相关文章:

c++ - 即使条目相同,也找不到 std::map 键

.net - 是否可以在具有 SOAP 对象的服务上使用多态性?

C++,复制集到 vector

c++ - 制作 boost http 客户端

c++ - 当使用 'auto' 时,从函数返回引用是否会导致创建新的临时对象?

c++ - 从 C++ 中的 Lambda 函数创建 Functor

testing - C++0x : noexcept(ndebug) for testing?

c++ - 在容器中正确使用多态性?

java - 为什么编译器显示错误

简单图像处理示例中的 C++AMP 异常