2011-10-05 163 views
2

我想知道是否可以重寫一個類中的一個函數而不創建一個全新的類。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

回答

0

您可以通過簡單的更改獲得所需的行爲,即將「虛擬」行爲移動到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

1

爲了改變虛函數,你必須創建一個新類型 - 在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