2014-05-17 39 views
0

我最近開始使用Qt框架,並意識到可能有一點關於C++的語法,我不太明白。舉例來說,當在Qt中啓動一個Widget項目時,這個代碼就是基礎。可能與C++有關的Qt代碼問題

MainWindow::MainWindow(QWidget *parent) :  
    QMainWindow(parent),      
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

所在類別MainWindow被定義爲:

namespace Ui { 
    class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

private: 
    Ui::MainWindow *ui; 
}; 

類聲明

  • 通過這個步進,我可以看到一個新的命名空間,Ui,被建造。我認爲這是一個實現努力,以避免與其他用戶實現的類命名衝突。

  • 下面是一個新的類定義;它繼承了QMainWindow,所以我們實質上是在創建一個自定義窗口對象。

  • Q_OBJECT顯然是一個允許用戶在類定義中使用信號和插槽的宏,但我現在不太擔心該代碼。

  • 我們將構造函數定義爲explicit,從而不允許此類類型的任何隱式轉換。還有一個析構函數顯示。

  • 在私人訪問中,我們查看Ui名稱空間並創建一個MainWindow指針。

類定義

  • 我們正在使用的初始化列表我明白,但我這裏迷路。我發現我們有一個默認參數爲NULL(或0)爲這個小部件的父,但如果一個類inherents另一類爲什麼你必須顯式調用所述繼承類的構造函數?那就是:

    class A { 
    } 
    
    class B : public A { 
    } 
    
    B testObject; 
    

這難道不是自動堆棧足夠的內存來同時包含A和B級分配內存?爲什麼上面顯示的Qt代碼在它自己的構造函數中爲繼承的類調用構造函數?

  • 繼續初始化列表的第二個參數,我必須說我對這裏使用的語法感到困惑。爲什麼我們有一個指向QMainWindow的指針,我們通過調用QMainWindow的構造函數進一步調用new來初始化,從而創建它自己的一個實例?這個初始化方法似乎是循環

  • 然後,我們調用setupUi函數並通過this對象進行初始化。

  • 最後,在析構函數中,我們簡單地釋放與MainWindow關聯的內存。

至於最後一個問題,如果創建一個額外的對象,說QPushButton,並在軟件自動收回與這些對象assocated內存或者必須是包含在析構函數一起delete ui?我還沒有看到實際做到這一點的教程,因此我不確定該框架是否設計成可以爲您處理。

我知道這裏很少有直接的問題,但是在我的邏輯中,每個陳述都有缺陷嗎?

tl; dr,跳到類定義下的第一個和第二個項目符號。

+0

我的印象是,在編譯時會添加一個默認的構造函數來初始化基礎。那麼QMainWindow繼承的類呢?我知道類只能在下面的層上調用構造函數,但除非QMainWindow的繼承類有一些「全部」構造函數,否則我們會遇到一些麻煩。另外,謝謝你的收穫! – sherrellbc

回答

2

請注意,你不應該在一個問題問這麼多子的問題,但我會盡量回答你的問題,無論...

這難道不是堆足自動分配內存內存包含類A和B?

它爲基類分配內存,是的。

爲什麼上面顯示的Qt代碼在它自己的構造函數中調用繼承類的構造函數?

因爲這就是C++繼承的工作原理。你需要在像這樣的情況下明確地初始化基類。它可能隱含在一個理想的默認構造函數中,但你甚至沒有在這裏使用它。

爲什麼我們有一個指向QMainWindow的指針,我們通過調用QMainWindow的構造函數並進一步調用new來初始化,從而創建它自己的實例?這個初始化方法似乎是循環正如你在開始時所描述的那樣,你有兩個獨立的MainWindow,一個由Qt Designer生成,一個在你的代碼中實現,因此你提到的命名空間。作爲最後一個問題,如果創建了一個額外的對象,比如QPushButton,軟件會自動釋放與這些對象關聯的內存,還是必須將它們與析構函數一起包含在刪除用戶界面中?我還沒有看到實際做到這一點的教程,因此我不確定該框架是否設計成可以爲您處理。

如果你在堆棧上分配它,這是沒有必要的,因爲它將在超出範圍時自動銷燬。如果你在堆上分配它,在Qt世界中,你指定父對象作爲構造函數的參數,以便在父對象被刪除時自動刪除它。這是通過Qt parent-child hierarchy and mechanism透明地完成的。這就是爲什麼你通常不會在例子中看到明確的刪除。

+0

非常好的解釋。我仍然不確定你在帖子中回答的第三個問題。當我第一次在Qt中看到這個時,我感到困惑,並編輯了一些代碼來使用它,而不是上面顯示的那樣:'ui = new Ui :: MainWindow;'(它當前所在塊之外)。這對我來說完全有意義。我知道我們需要爲這個對象分配堆,但是調用MainWindow的構造函數來調用'new'來爲自己分配內存是循環的,並且讓我感到困惑。構造函數甚至會將參數作爲參數? '主窗口(主窗口*)'? – sherrellbc

+0

@sherrellbc:這裏沒有圓形的東西。 'new Ui :: MainWindow'是'Ui'命名空間中的UI類,而'MainWindow :: MainWindow'是'Ui'命名空間之外的MainWindow類*。你可以在這裏找到更多關於C++命名空間的信息(http://www.cplusplus.com/doc/tutorial/namespaces/)。 – lpapp