2015-06-15 33 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