构造函数不支持多态

今天在写项目的时候,需要使用到多态的效果,因此就设计了三个类,一个基类,一个派生类,外加一个派生类中需要使用到的界面类。
大体结构如下:

///< 基类 >

// 头文件
#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_wgttest.h"

class QTabWidget;

class WgtTest : public QMainWindow
{
    Q_OBJECT

public:
    WgtTest(QWidget *parent = Q_NULLPTR);

protected:
    virtual void initWgt();

    virtual void initTagWgt(){} // 不执行任何操作

 protected:
    Ui::WgtTestClass ui;

    QTabWidget* m_tabWgt;
};


// 源文件
#include <QTabWidget>
#include <QGridLayout>
#include <QHBoxLayout>

#include "wgttest.h"

WgtTest::WgtTest(QWidget *parent)
    : QMainWindow(parent)
    , m_tabWgt(new QTabWidget(this))
{
    ui.setupUi(this);

    initWgt();
}

void WgtTest::initWgt()
{
    QHBoxLayout* pLayout = new QHBoxLayout;
    pLayout->addWidget(m_tabWgt);
    ui.widget->setLayout(pLayout);

    initTagWgt();
}
//< 派生类 >

// 头文件
#pragma once

#include "wgttest.h"

class FrmChildWgt1 : public WgtTest
{
	Q_OBJECT

public:
	FrmChildWgt1(QWidget *parent = nullptr);
	~FrmChildWgt1();

protected:
	virtual void initTagWgt() override;
};

// 源文件
#include "frmchildwgt1.h"
#include "frmwgt1.h"

FrmChildWgt1::FrmChildWgt1(QWidget *parent)
	: WgtTest(parent)
{
}

FrmChildWgt1::~FrmChildWgt1()
{
}

void FrmChildWgt1::initTagWgt()
{
	FrmWgt1* wgt = new FrmWgt1(m_tabWgt);
	m_tabWgt->addTab(wgt, "test_tab1");
}

还有一个类是培生累中用到的界面类,直接上图吧:
在这里插入图片描述
然后在main.cpp文件中如下书写:

#include "wgttest.h"
#include <QtWidgets/QApplication>
#include "frmchildwgt1.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

	// 使用方式1(派生类对象)
    FrmChildWgt1 w;
    w.show();

	// 使用方式2(派生类指针)
    //FrmChildWgt1* pWgt = new FrmChildWgt1;
    //pWgt->show();

	// 使用方法3(基类指针指向派生类对象)
    //WgtTest* pWgt = new FrmChildWgt1;
    //pWgt->show();
    return a.exec();
}

其中使用了三种方式,结果发现界面始终都是基类的界面,如下所始终没有出现派生类的界面。
在这里插入图片描述

后查阅资料后发现,原因出在 —— 构造函数中无法实现多态

至于其原因,可很好理解,在构造一个对象的时候,首先会调用其基类的构造函数,执行基类构造函数中的代码,而此时,其派生类还没有被构造,这就导致即便派生类中重写了某个虚函数,但是还是无法被调用的情况
子类构造时,先会调用父类构造函数,父类构造函数中调用initTabWg(),虽然它是一个虚函数,但是此时子类还处于构造过程中并没有构建完成,因此无法调用派生类的实现,只能调用父类本身的实现,我们看到的就是无法呈现多态了

鉴于此,将上述代码中的initWgt()函数暴露出来,作为接口,随后取消在构造函数中的调用,紧接着在构造完基类之后,执行initWgt()函数即可实现多态效果,如下:

 public:
    virtual void initWgt();

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    WgtTest* pWgt = new FrmChildWgt1;
    pWgt->initWgt();
    pWgt->show();
    return a.exec();
}

此时就可正确调用派生类中的函数了,界面如下:
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值