C ++ переопределить функцию объекта, созданного подклассом - PullRequest
3 голосов
/ 05 октября 2011

Мне было интересно, можно ли переопределить только одну функцию в классе, не создавая совершенно новый класс.

Я бы хотел bObj1.foo(); вывести "foo!" и bObj2.foo() для вывода «foo?», но в настоящее время они оба выводят «foo!».

#include <iostream>
using namespace std;

class B {
    public:
    virtual void foo() { cout << "foo!" << endl; }
};

class A {
    public:
    B f();
};

B A::f() {
    B bObj;
    return bObj;
}

class C : public A {
};

int main()
{
    A aObj;
    B bObj1 = aObj.f();
    bObj1.foo(); // "foo!"

    C cObj;
    B bObj2 = cObj.f();
    bObj2.foo(); // "foo?"
}

Ответы [ 2 ]

1 голос
/ 05 октября 2011

Вы можете получить желаемое поведение с помощью простого изменения, заключающегося в переносе «виртуального» поведения в классы A и C.

Здесь я изменил ваше приложение, чтобы получить ожидаемый результат:

#include <iostream>
using namespace std;

class A;

class B {
public:
    B(A& a) : aref(a) {}
    void foo();
private:
    A& aref;
};

class A {
public:
    B f();
    virtual void foo() { cout << "foo!" << endl; }
};

B A::f() {
    B bObj(*this);
    return bObj;
}

class C : public A {
public:
    virtual void foo() { cout << "foo?" << endl; }
};

void B::foo() { aref.foo(); }

int main()
{
    A aObj;
    B bObj1 = aObj.f();
    bObj1.foo(); // "foo!"

    C cObj;
    B bObj2 = cObj.f();
    bObj2.foo(); // "foo?"
}
1 голос
/ 05 октября 2011

Чтобы изменить виртуальную функцию, вы должны создать новый тип - в C ++ этого нет. Однако альтернативный механизм - функциональные объекты - может делать то, что вы хотите здесь.

#include <functional>
#include <iostream>

using namespace std;

class B {
public:
    B(function<void ()> foo_impl) : foo_impl(foo_impl) {}

    void foo() {foo_impl();}
private:
    function<void()> foo_impl;
};

class A {
public:
    virtual B f();
};

B A::f() {
    B bObj([](){cout << "foo!" << endl;});
    return bObj;
}

class C : public A {
public:
    virtual B f() override;
};

B C::f() {
    B bObj([](){cout << "foo?" << endl;});
    return bObj;
}

int main()
{
    A aObj;
    B bObj1 = aObj.f();
    bObj1.foo(); // "foo!"

    C cObj;
    B bObj2 = cObj.f();
    bObj2.foo(); // "foo?"
}
...