使用信号/插槽来避免循环依赖?

时间:2014-01-09 20:20:14

标签: c++ qt signals qt-signals

我有一块不雅的C ++ Qt代码,其中main创建了一个图形项(父项),它创建了一堆子图形项。孩子和父母必须互相称呼方法,即父母需要告诉孩子做一些事情(移动,改变颜色等),孩子们会发信号通知父母对其他孩子做事。两个人都打电话给对方'方法导致一些丑陋的循环代码,并且令人沮丧地避开C2027错误。使用自定义信号/插槽系统作为孩子和父母之间的沟通方式是否有意义?或者我应该坚持我当前的设计课程,并尝试解决这些类型的错误?

例如,此代码(我当前的设计)生成C2027:

主窗口:

#include "mainwindow.h"
#include "ui_mainwindow.h"

vector<Foo*> FooArray;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    scene = new QGraphicsScene(this);
    ui->graphicsView->setScene(scene);

    int viewwidth = ui->graphicsView->width();

    ...

    FooArray.push_back(new Foo(5, viewwidth, scene));
    FooArray[0]->loadBars();
}

Foo:

#include "Foo.h"  //includes bar.h


vector<int> ActiveList;
vector<Bar*> BarArray;

Foo::Foo(int id, int w, QGraphicsScene* scene)
{
    this->id = id;
    this->width = w;
    this->scene = scene;
}

...

void Foo::loadBars()
{
    ...
    BarArray.resize(nitems);
    BarArray[k] = new Bar(id, k, this);
    BarArray[k]->setPos(...);
    scene->addItem(BarArray[k]);
    ...
}

void Foo::doSomething()
{
    ...
}

酒吧:

#include "Bar.h"  //forward declares Foo; isn't executed until Foo exists. 

Bar::Bar(int setid, int num, Foo* foo)
{
    this->s = setid;
    this->n = num;
    this->owner = foo;
}

...

void Bar::someFunction()
{   
    ...
    owner->doSomething();
    ...
}

1 个答案:

答案 0 :(得分:3)

是的,这正是信号和插槽的用途。

现在你有Bar::someFunction()来调用Foo::doSomething()

你能做的是:

  1. doSomething()声明为广告位
  2. 让条形码发出信号somethingHappened()
  3. 创建孩子时,将他们的somethingHappened()信号连接到父母的doSomething()位置
  4. 这是依赖注入的一个示例,它允许您在将来交换父类以获取其他内容,而无需更改Bar