priority_queue top按引用返回

时间:2018-01-10 05:19:08

标签: c++ inheritance priority-queue

我有以下priority_queue类型为base的项目。 问题是,当我使用top()从队列中获取项目时, 然后通过基础引用对象调用它的f()函数,它会调用它 基类的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;

    }

2 个答案:

答案 0 :(得分:1)

与使用指针相同的多态前提,但这是使用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;
}

答案 1 :(得分:1)

您应该使用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;

}