在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
问题现象:使用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 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 } 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 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 } 总结:如果不调用“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. 总结:如果使用了“virtual”和“override”的话,如果用派生类实例实体对象,会直接调用派生成的初始化方法。
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论