C++重写由子类创建的对象的函数

问题描述:

我想知道是否可以重写一个类中的一个函数而不创建一个全新的类。C++重写由子类创建的对象的函数

我想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?" 
} 
+1

你想用它的虚拟功能之一的自定义替代返回一个对象?这对于虚拟功能来说并不是真的可能 - 它正在进入功能对象领域。你能举一个你如何使用这个例子吗?在你的例子中,单词“foo?”不存在。 – Ayjay

+0

是的。我想返回一个'B',它的'foo()'被覆盖。 – Jeremiah

+0

原因是'A ::'确实是一个链表,'B ::'确实是一个迭代器。我将'A ::'继承到'C ::',并希望'C ::'具有不同的迭代器行为。我坚持这种设计。 – Jeremiah

您可以通过简单的更改获得所需的行为,即将“虚拟”行为移动到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?" 
} 
+0

这绝对有帮助。翻转事物的好方法。 – Jeremiah

为了改变虚函数,你必须创建一个新类型 - 在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?" 
} 
+0

这看起来很有趣。这会让我有点消化。谢谢。 – Jeremiah