priority_queue 顶部 return 参考

priority_queue top return by reference

我有以下 priority_queue 类型的项目。 问题是,当我使用 top() 从队列中获取项目时, 然后通过基引用对象调用它的 f() 函数,它确实调用了 基数 class 的 f,但不是覆盖的 f。 我想要调用子对象的 f() 。 有什么帮助吗?谢谢..

    #include <queue>
    #include <iostream>

    using namespace std;

    class base {

        public:
            int id;

            virtual void f() const {

                cout << "base f()" << endl;
            }

    };

    class D1: public base {

        public:

            void f() const {

                cout << "D1 f()" << endl;
            }

    };

    class D2: public base {

        public:

            void f() const {

                cout << "D2 f()" << endl;
            }

    };

    bool operator<(const base& b1, const base& b2)
            {
        return b1.id > b2.id;
    }

    int main()
    {

        priority_queue<base, deque<base>, less<deque<base>::value_type> > Q;

        D1 d1;
        D2 d2;

        Q.push(d1);
        Q.push(d2);

// this is not something  I want
        const base& b = Q.top();
        b.f();        // base f()


// this works as I want
    const base& b2 = d2;
    b2.f();        // D1 f()

    return 0;

    }

与使用指针相同的多态前提,但这里有一个可能的替代方案,使用 std::reference_wrapper:

#include <functional>
#include <queue>
#include <iostream>

using namespace std;

class base {
    public:
        int id;

        virtual void f() const {
            cout << "base f()" << endl;
        }
};

class D1: public base {
    public:
        void f() const {
            cout << "D1 f()" << endl;
        }
};

class D2: public base {
    public:
        void f() const {
            cout << "D2 f()" << endl;
        }
};

bool operator<(const base& b1, const base& b2)
{
    return b1.id > b2.id;
}

int main()
{

    priority_queue<std::reference_wrapper<base>, deque<std::reference_wrapper<base>>, less<deque<std::reference_wrapper<base>>::value_type> > Q;

    D1 d1;
    D2 d2;

    Q.push(d1);
    Q.push(d2);

    // this now works as you want?
    const auto& b = Q.top();
    b.get().f();    // D1 f()


    // this works as I want
    const auto& b2 = d2;
    b2.f();        // D2 f()

    return 0;
}

您应该使用 shared_ptr,因为它们本质上是多态的。下面的代码使用 shared_ptr

实现了你想要的
#include <queue>
#include <iostream>

using namespace std;

class base {

    public:
        int id;

        virtual void f() const {

            cout << "base f()" << endl;
        }

};

class D1: public base {

    public:

        void f() const {

            cout << "D1 f()" << endl;
        }

};

class D2: public base {

    public:

        void f() const {

            cout << "D2 f()" << endl;
        }

};

bool operator<(const base& b1, const base& b2)
{
    return b1.id > b2.id;
}

int main()
{

    priority_queue<std::shared_ptr<base>, deque<std::shared_ptr<base>>, less<deque<std::shared_ptr<base>>::value_type>> Q;

    D1 d1;
    D2 d2;

    Q.push(std::make_shared<D1>(d1));
    Q.push(std::make_shared<D2>(d2));

    // Works!
    const shared_ptr<base> b = Q.top();
    b->f();        // D1 f()

    return 0;

}