【问题标题】:Use the derived class value from the base class使用来自基类的派生类值
【发布时间】:2012-02-02 22:43:56
【问题描述】:

尝试在基类中创建一个小部件,而根据我们调用的派生类,小部件中唯一会改变的是标题。

class BaseView : public QWidget {
    Q_OBJECT
public:
     explicit BaseView(QWidget *parent = 0);
protected:
     QString title; 
     virtual QString getTitle() const {
         return title;
     }

BaseView.cpp:

BaseView::BaseView(QWidget *parent) : QWidget(parent) {

     title = "test"
}

void BaseView::createTopWidget() {
    QGroupBox *topWidget = new QGroupBox(getTitle());
    ....
}

派生类头中的:

class DerivedView : public BaseView {
    Q_OBJECT
public:
     explicit DerivedView(QWidget *parent = 0);
protected:
     QString getTitle() const {
         return title;
     }

在派生的构造函数中,我将标题设置为“正确”。

当我通过创建 DerivedView 运行程序时,标题仍然是“测试”。我该怎么做才能从基类调用并获取派生类值?

【问题讨论】:

  • getTitlegetTopWidgetMessage是什么关系?即,您将 getTitle 定义为虚拟但从不在任何地方调用它——有什么意义?
  • 哦,他们应该是一样的。在本例中重命名了它们,但忘记全部重命名。

标签: c++ qt


【解决方案1】:

除非你对 C++ 非常熟悉,你不能在构造函数中调用虚函数。问题是在子对象创建过程中,对象的类型是基础子对象,而不是派生对象,所以虚函数调用被分派给了“错误”的函数。

宝贝示例:

struct Base
{
    virtual int foo() { return 8; }

    Base() { set_something(foo()); }  // who're you gonna call?
};
struct Derived
{
    virtual int foo() { return -12; }
};

Derived d;

现在在d.Base() 的基本构造函数中,被调用的函数是d.Base::foo(),而不是d.Derived::foo()

而且,在基类构造函数运行时,成员变量title只被设置为"test",它还没有被派生构造函数中的赋值覆盖,它只运行基础构造函数完成之后。

您可以通过在构造函数中显式传递标题来解决您的问题:

class BaseView : public QWidget
{
public:
    BaseView(QWidget * parent = 0, QString const & t = "test")
    : QWidget(parent), title(t)
    {
        something.set_title(title);
    }

    // ...
};

class DerivedView
{
public:
    DerivedView(QWidget * parent = 0)
    : BaseView(parent, "correct")
    { }
};

【讨论】:

  • 哦,好吧。是的,我认为基类不能很容易地从其派生类中获取东西。但是,还有其他方法可以做到这一点吗?标题字符串会很长,我将对其他对象做同样的事情。我想我可能不得不放弃创建一切的基类的想法..
  • @chikuba:查看我的更新;我会在构造函数中传递所有必需的信息,然后在派生构造函数中调用所需的初始化程序。
  • 另外,我注意到您更改了派生视图的构造函数。如果派生视图有一个父视图(另一个小部件),该父视图是否也被发送到基础视图?我看不出为什么派生的小部件会成为 baseview 的父级。
  • 这是一种常见的做事方式还是我应该想出另一种解决方案?可能会在派生类中初始化组框
  • 另外,你说我永远不应该在构造函数中调用虚拟函数,我不这样做。那为什么我还有问题?是不是因为我运行了使用构造函数中的变量的函数,并且在完成之前不会调用派生构造函数?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-04
相关资源
最近更新 更多