2015-06-15 68 views
1

背景:我有Qt生成的沒有共同祖先的UI類。我使用這些UI類之一繼承一個類(比如說「Door」),而派生類(「OakDoor」)將使用不同的UI類,儘管大多數UI元素將具有相同的名稱。如何覆蓋基類的( - >)運算符的成員

到現在爲止,我一直在隱藏基類UI類(即派生類使用不同類型但同名的UI類),但現在需要依靠繼承來處理基類在UI上工作的情況班;在這種情況下隱藏不起作用。

我已經問過使用繼承來做到這一點的方法,並指出了使用組合的方向。所以我試圖找到一種有效的方法來做到這一點,而無需爲每個UI元素定義訪問函數。這不是真正的組合,但我認爲它讓我接近一點努力。

class form_container 
{ 
public: 
    form_container(){}; 
    form_container(Ui_A_Form * form){_form = form;} 
    ~form_container(){ delete _form; } 
    Ui_A_Form *_form; 
    Ui_A_Form & operator->() 
    { 
    return *_form; 
    } 
}; 

當時的想法是再有門使用這個類和OakDoor它的一個子類:

class B_form_container : public form_container 
{ 
public: 
    B_form_container(Ui_B_Form * form){_form=form;} 
    ~B_form_container(){delete _form;} 
    Ui_B_Form *_form; 
    Ui_B_Form & operator->() 
    { 
    return *_form; 
    } 
}; 

所以我真的只是轉移藏匿。無論如何,這個問題似乎與我的操作符重載 - >()。 在我的Door課上,我有 form_container *_myform; 它正是如此構造:

_myform = new form_container(new A_Form()); 

但是當我嘗試在A_Form訪問任何它不會編譯,比如Qt的SetupUI功能:

_myform-> setupUi(_a_widget);

我明顯在做錯事。將不勝感激任何幫助 - 非常感謝! (我可以看到問題,當子類試圖刪除_form在基類,但我會稍後排序)

編輯:好吧這是編譯現在(非常感謝@(R Sahu)),但我沒有看到我期望的超載。例如:

class base_class() 
{ 
    form_container *_myform; 
}; 

class derived_class(): public base_class() 
{ 
//inherit _myform; 
}; 

//(constructor for derived class) 
derived_class()::derived_class() 
{ 
    _myform = new B_form_container(new B_form()); 
    (*_myform)->setupUI(new QWidget()); // tries to setupUi on an A_form 
} 

這是調用form_container :: operator - >(),大概是因爲它不是虛擬的。如果我在基類form_container中將其虛擬化,則派生類B_form_container會對函數的區別僅在於返回類型。 有沒有辦法解決這個問題? 我能爲實例做這樣的事情:

class base : public A_form 
{ 
virtual base * operator->() 
{ 
    // not sure how to return ->() operator of A_form 
    return A_form::operator->(); // ??? 
} 
}; 

class derived : public base, public B_form 
{ 
virtual base *operator->() 
{ 
    return B_form::operator->(); // again??? 
} 
} ; 

另一個編輯:我不認爲我所試圖做的是可能的了。如果你能糾正我,請做。在此期間,我寫了一些東西來處理moc輸出,並創建具有訪問功能的類,我可以用覆蓋。

+0

請提供[最小,完整,可驗證示例](http://www.stackoverflow.com/help/mcve)。 – Barry

+0

看起來你嘗試的越多,意義越小......如果'derived'從'base'派生,那麼它間接地從'A_form'派生。因此派生出'A_form'或'B_form'。 – Phil1970

回答

0

正如我最終意識到的那樣,這是不可能的。運算符 - >()必須返回它所代理的類型,因此它不能用作虛擬函數。

+0

「真正的」虛擬功能對此也不起作用。這些都需要有相同的簽名。當然,您可以同時將「UI _?_ Form」類與相關的虛函數共同使用,並通過引用/指向該基的多指針來訪問它們(從而保留簽名)。 –

+0

這正是我所做的。我最終編寫了一個小實用程序來接收.ui文件,並自動編寫具有虛函數的基類。我在編譯.ui文件時將其稱爲構建步驟,因此一旦建立,它就非常方便。 – mike

+0

酷!是的,多態性真的很酷。結合模板,我不確定任何其他語言都會給我這麼多的能力來創建一個複雜的模板類型意義_but_給它們一個共同的基礎接口。在第二個想法,也許我不應該有這麼多的權力。 :D –

4
_myform = new form_container(new A_Form()); 
_myform->setupUi(_a_widget); 

不是用來訪問operator->()函數的正確語法。使用該語法,編譯器需要form_container類中的成員函數setupUi()。正確的語法是:

_myform = new form_container(new A_Form()); 
(*_myform)->setupUi(_a_widget); 
// This translates to: 
// Invoke the operator->() function on (*_myform) 
// Use the return value of the function and call `setupUi()` on the returned pointer. 

_myform = form_container(new A_Form()); 
_myform->setupUi(_a_widget); 

此外,函數需要返回一個指針,而不是一個參考。

Ui_B_Form* operator->() 
{ 
    return _form; 
} 
+0

感謝您清理參考資料,這就是我原來的。它會編譯,如果我使用你的第一次更正(_myform是一個form_container *)。你能解釋爲什麼我需要解除引用_myform才能使用操作符? – mike

+0

@mike,查看最新的答案。 –

+0

好的感謝 - 標記爲答案 – mike