zoukankan      html  css  js  c++  java
  • Qt和Delphi在面向对象时使用virtual不同之处?

    问题现象:使用Qt在做OSG开发时,我需要建立点、线、面的实体,这时使用初始化方法时,发现都是使用的基类的方法。

    问题原因:在Qt(包括该死的C++)中使用virtual和Delphi中有手法上的不同。

    问题处理:在派生类中再调用一次初始化方法,或者是参数创建方法。

    代码展示:

    Qt版本:

    .pro文件是原生的,没有修改

     1 QT       += core gui
     2 
     3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
     4 
     5 CONFIG += c++11
     6 
     7 # The following define makes your compiler emit warnings if you use
     8 # any Qt feature that has been marked deprecated (the exact warnings
     9 # depend on your compiler). Please consult the documentation of the
    10 # deprecated API in order to know how to port your code away from it.
    11 DEFINES += QT_DEPRECATED_WARNINGS
    12 
    13 # You can also make your code fail to compile if it uses deprecated APIs.
    14 # In order to do so, uncomment the following line.
    15 # You can also select to disable deprecated APIs only up to a certain version of Qt.
    16 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    17 
    18 SOURCES += 
    19     main.cpp 
    20     mainwindow.cpp
    21 
    22 HEADERS += 
    23     mainwindow.h
    24 
    25 FORMS += 
    26     mainwindow.ui
    27 
    28 # Default rules for deployment.
    29 qnx: target.path = /tmp/$${TARGET}/bin
    30 else: unix:!android: target.path = /opt/$${TARGET}/bin
    31 !isEmpty(target.path): INSTALLS += target
    View Code

    main.h文件是原生的,没有修改

     1 #include "mainwindow.h"
     2 
     3 #include <QApplication>
     4 
     5 int main(int argc, char *argv[])
     6 {
     7     QApplication a(argc, argv);
     8     MainWindow w;
     9     w.show();
    10     return a.exec();
    11 }
    View Code

    mainwindow.h 增加了三个测试类

     1 #ifndef MAINWINDOW_H
     2 #define MAINWINDOW_H
     3 
     4 #include <QMainWindow>
     5 #include <QDebug>
     6 
     7 // 测试类
     8 class ta :public QObject
     9 {
    10 public:
    11     ta();
    12     int id;
    13     virtual void init();
    14 };
    15 // 测试类
    16 class tb : public ta
    17 {
    18 public:
    19     tb();
    20     virtual void init() override;
    21 };
    22 // 测试类
    23 class tc : public ta
    24 {
    25 public:
    26     tc();
    27     virtual void init() override;
    28 };
    29 
    30 
    31 QT_BEGIN_NAMESPACE
    32 namespace Ui { class MainWindow; }
    33 QT_END_NAMESPACE
    34 
    35 class MainWindow : public QMainWindow
    36 {
    37     Q_OBJECT
    38 
    39 public:
    40     MainWindow(QWidget *parent = nullptr);
    41     ~MainWindow();
    42 
    43 private slots:
    44     void on_pushButton_clicked();
    45 
    46 private:
    47     Ui::MainWindow *ui;
    48     QList<ta *> olist;
    49 };
    50 #endif // MAINWINDOW_H
    View Code

    mainwindow.cpp三个类的实现,在创建事件下建立测试类的实体对象

     1 #include "mainwindow.h"
     2 #include "ui_mainwindow.h"
     3 
     4 MainWindow::MainWindow(QWidget *parent)
     5     : QMainWindow(parent)
     6     , ui(new Ui::MainWindow)
     7 {
     8     ui->setupUi(this);
     9 
    10     tb *ob = new tb();
    11     ob->init();// 调用派生类初始化方法
    12     olist.append(ob);
    13     qDebug() << ob->id;
    14 
    15     tc *oc = new tc();
    16     oc->init();// 调用派生类初始化方法
    17     olist.append(oc);
    18     qDebug() << oc->id;
    19 }
    20 
    21 MainWindow::~MainWindow()
    22 {
    23     delete ui;
    24 }
    25 
    26 
    27 void MainWindow::on_pushButton_clicked()
    28 {
    29   for (int i = 0; i < olist.size(); i++)
    30   {
    31       tb *ob = dynamic_cast<tb *>(olist[i]);
    32       if (ob)
    33       qDebug() << ob->id;
    34   }
    35 }
    36 
    37 ta::ta()
    38 {
    39     init();
    40 }
    41 
    42 void ta::init()
    43 {
    44     id = 1;
    45 }
    46 
    47 tb::tb()
    48    : ta()
    49 {
    50 
    51 }
    52 
    53 void tb::init()
    54 {
    55     id = 2;
    56 }
    57 
    58 tc::tc()
    59 {
    60 
    61 }
    62 
    63 void tc::init()
    64 {
    65     id = 3;
    66 }
    View Code

    总结:如果不调用“ob->init();// 调用派生类初始化方法”的话,会自动调用基类的初始化。必须手机调一下自己的初始化方法。

    Delphi版本:

     1 unit Unit1;
     2 
     3 interface
     4 
     5 uses
     6   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
     7   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
     8 
     9 type
    10   //测试类
    11   Ta = class(Tobject)
    12   public
    13     ID: integer;
    14     procedure setID(); virtual;
    15     constructor Create();
    16   end;
    17   //测试类
    18   Tb = class(Ta)
    19   public
    20     procedure setID(); override;
    21   end;
    22   //测试类
    23   Tc = class(Ta)
    24   public
    25     procedure setID(); override;
    26   end;
    27 
    28   TForm1 = class(TForm)
    29     procedure FormCreate(Sender: TObject);
    30   private
    31     { Private declarations }
    32   public
    33     { Public declarations }
    34   end;
    35 
    36 var
    37   Form1: TForm1;
    38 
    39 implementation
    40 
    41 {$R *.dfm}
    42 
    43 { Ta }
    44 
    45 constructor Ta.Create;
    46 begin
    47   inherited;
    48   setID;
    49 end;
    50 
    51 procedure Ta.setID;
    52 begin
    53   id := 1;
    54 end;
    55 
    56 { Tb }
    57 
    58 procedure Tb.setID;
    59 begin
    60   inherited;
    61   id := 2;
    62 end;
    63 
    64 { Tc }
    65 
    66 procedure Tc.setID;
    67 begin
    68   inherited;
    69   id := 3;
    70 end;
    71 
    72 procedure TForm1.FormCreate(Sender: TObject);
    73 var
    74   ob: Tb;
    75   oc: Tc;
    76 begin
    77   ob := Tb.Create(); //调用自己的初始化
    78   oc := Tc.Create(); //调用自己的初始化
    79 end;
    80 
    81 end.
    View Code

    总结:如果使用了“virtual”和“override”的话,如果用派生类实例实体对象,会直接调用派生成的初始化方法。

  • 相关阅读:
    slqmap简单使用
    Sql注入类型
    路由器协议----IGP、EGP、RIP、OSPF、BGP、MPLS
    TCPIP协议簇-各层主要协议帧格式
    TCP/IP协议(7):应用层
    TCP/IP协议(5):传输层之TCP
    TCP/IP协议(6):传输层之UDP
    Mysql数据库优化之SQL及索引优化
    公众号支付时,如何判断是否是微信浏览器
    ajax返回数据为undefined
  • 原文地址:https://www.cnblogs.com/FKdelphi/p/13605517.html
Copyright © 2011-2022 走看看