2016-02-16 62 views
-1

我一直在研究一個我現在面臨的bug,事實證明,C++在運行時(並調用主函數)之前初始化類。然而,我的程序是一個opengl程序,需要在完成其他任何事情之前設置某些東西。是否有任何方法可以解決這個問題?問題很簡單,但這裏有一些pseudo/C++代碼:C++執行流程

class shader 
{ 
    shader() { /* constructor... DEPENDS ON GL SET UP! But called first!*/ } 
} 

// global/static shaders 
shader geometry; 
shader lighting; 

int main() 
{ 
    glewInit(); // initialize opengl 
} 

編輯:增加了一些基於評論的信息。是的,我的着色器類是靜態的,它們是問題。唯一的解決辦法是在main初始化完成後將這些靜態類轉換爲指針並分配它們?或者有沒有辦法延遲初始化?

+0

單獨的代碼不會調用構造函數。你大概也有一個靜態存儲持續時間的'shader'類型的對象。 – aschepler

+0

是的,我所有的着色器都是靜態的。所以他們正在我的主要功能之前構建? – Jas

+3

僞代碼不會幫助。請提供[MCVE](http://stackoverflow.com/help/mcve)來演示。這聽起來像你正在使用靜態,這是在你輸入'main'之前初始化的。 – paddy

回答

2

您應該停止將代碼放入需要調用glewInit的全局變量的構造函數中。

事實上,避免讓全局變量的構造函數或析構函數做任何事情是一個好主意,因爲全局變量初始化的順序不明確。擁有全局析構函數會讓你的關機序列更加困難。

如果你想使用一個全局變量,因爲它太令人討厭使用局部變量main()並將它傳遞到任何地方,那麼你將需要確保全局變量不會被初始化,直到後來纔會被初始化。要做到這一點的方法之一是把它放在一個函數:

shader &geometry() 
{ 
    static shader g; 
    return g; 
} 

,在你的頭文件,shader &geometry();,並確保沒有在任何地方與其他全局變量調用這個!直到第一次調用函數時,函數內部的靜態變量纔會被初始化。 (警告:你仍然無法控制的破壞爲了這樣 - 你將不能夠乾淨地破壞這種着色器,然後未初始化GL)

另一種方法是使用智能指針:

std::unique_ptr<shader> p_geometry; 

int main() 
{ 
    glewInit(); 

    p_geometry = std::make_unique<shader>(); 

    // use *p_geometry... 

    // If you want to shut down tidily 
    p_geometry.reset(nullptr);   
} 
+0

謝謝你,首先我應該做的。 – Jas

1

在任何函數或類之外聲明的對象被放置在全局範圍內。在執行main之前構建這樣的對象。這就是爲什麼你的對象是在OGL被初始化之前構造的。

這可能是你需要做什麼:

int main() 
{  
    glewInit(); // initalize opengl 

    shader geometry; 
    shader lighting; 
} 

只需移動shader物體插入main函數的局部範圍將確保當你想他們,他們被初始化 - 在glewInit()調用之後。

+0

如果着色器需要全局可訪問,這可能不是一個好的解決方案。 – immibis