[英]Qt signal-slot handling of private variables: feature or flaw?
我正在使用 Qt 庫編寫相當長的 c++ 代碼(超過 70K 行),並且在處理私有變量時遇到了信號槽機制的意外(對我而言)行為。
這個想法是,當 object(object1)使用包含前者(object1 的 vec1)的私有變量的信號與另一個(object2)通信時,后者(object2)能夠修改它。 我想知道這是否必須被視為一個功能或一個缺陷。
我在這里放了一個簡化的代碼來說明這個事實:object1 有一個名為 vec1(指針)的私有 QVector 變量,並向 object2 發送一個信號以刪除 vec1 的一些元素。 此 object2 捕獲信號並成功執行任務。
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow mainWin;
mainWin.show();
return a.exec();
}
主窗口.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
#include <QVBoxLayout>
#include "object1.h"
#include "object2.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
};
#endif // MAINWINDOW_H
主窗口.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QVector<int> * vec;
object1 *obj1 = new object1();
object2 *obj2 = new object2();
connect(obj1, SIGNAL(remove_items_signal1(QVector<int>*,int)),
obj2, SLOT(remove_items_slot2(QVector<int>*,int)));
vec = obj1->get_vec1();
QString str1("vec1 before removing any elements = ");
for (int i = 0 ; i < vec->length(); i++){
str1.append(QString(" %1").arg(vec->at(i)));
}
QLabel *label1 = new QLabel(str1);
// remove some elements at the end of the vector using the signal-slot mechanism
// Notice that the elements of vec1 (which is private of object1)
// are removed in object2.
int i = 3;
obj1->emit_remove_items(i);
vec = obj1->get_vec1();
QString str2("vec1 after removing the last " + QString("%1").arg(i) + " elements in object2 = ");
for (int i = 0 ; i < vec->length(); i++){
str2.append(QString(" %1").arg(vec->at(i)));
}
QLabel *label2 = new QLabel(str2);
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(label1);
layout->addWidget(label2);
QWidget *window = new QWidget();
window->setLayout(layout);
setCentralWidget(window);
}
MainWindow::~MainWindow()
{
}
對象1.h
#ifndef OBJECT1_H
#define OBJECT1_H
#include <QWidget>
#include <QVector>
class object1 : public QWidget
{
Q_OBJECT
public:
explicit object1(QWidget *parent = 0);
~object1();
void emit_remove_items(int);
QVector<int> * get_vec1();
signals:
void remove_items_signal1(QVector<int> *, int);
private:
QVector<int> *vec1;
};
#endif // OBJECT1_H
對象1.cpp
#include "object1.h"
object1::object1(QWidget *parent) : QWidget(parent)
{
vec1 = new QVector<int>();
*vec1 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9;
}
object1::~object1(){
}
void object1::emit_remove_items(int i){
emit remove_items_signal1(vec1, i);
}
QVector<int>* object1::get_vec1(){
return vec1;
}
對象2.h
#ifndef OBJECT2_H
#define OBJECT2_H
#include <QWidget>
#include <QVector>
class object2 : public QWidget
{
Q_OBJECT
public:
explicit object2(QWidget *parent = 0);
~object2();
public slots:
void remove_items_slot2(QVector<int> *, int);
private:
QVector<int> *vec2;
};
#endif // OBJECT2_H
對象2.cpp
#include "object2.h"
object2::object2(QWidget *parent) : QWidget(parent)
{
vec2 = new QVector<int>();
}
object2::~object2(){
}
void object2::remove_items_slot2(QVector<int> * vec1, int i){
vec2 = vec1;
if (i < vec2->length()){
int j = vec2->length()-i;
vec2->remove(j,i);
}
}
這並不奇怪,因為信號/插槽正在做一些奇怪的事情。 您的成員 function object1::emit_remove_items
將對私有成員vec1
的引用傳遞給信號remove_items_signal1
(這只是另一個函數)。 將此信號連接到插槽使信號實現調用該插槽(這只是另一個函數)。
不過,您對信號/插槽模式的使用有點奇怪,因為您將object1
的私有部分放棄給object2
,正如您所注意到的那樣,這破壞了封裝。
確保:
somethingChanged
、 somethingEnded
、doSomething
、 endSomething
。應用這些准則,然后更改您的代碼以實現它們甚至可能使奇怪的私有指針傳遞部分 go 消失。 如果沒有,你需要重新考慮你到底想要完成什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.