2014-01-09 59 views
1

我有一個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(); 
} 

富:

#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(); 
    ... 
} 

回答

3

是,這正是什麼信號和插槽是爲了。

現在你有Bar::someFunction()這就要求Foo::doSomething()

你可以做的反而是:

  1. 聲明doSomething()作爲插槽
  2. 有無酒吧發出的信號somethingHappened()
  3. 在創建兒童,將它們的somethingHappened()信號連接到父母的doSomething()插槽

這是一個依賴注入的例子,它允許您將父類替換爲未來的其他東西,而不必更改Bar

相關問題