2016-07-01 32 views
0

因此,我正在嘗試編寫一個資源加載器和管理器(是的,我知道Thor,這只是一個「學習」項目。),我開始嘗試使用工會,我經常使用。我創建了一個類(如下面的代碼所示),稱爲具有包含紋理/字體的聯合的資源。紋理加載正確;但是字體會引發訪問衝突Resource union爲SFML中的字體拋出訪問衝突

Exception thrown at 0x00C5DBE0 in Project.exe: 0xC0000005: Access violation reading location 0x00000004. 

以下是我完整且最小的示例。編輯::更新的代碼解決了這個問題。埃文在下面解釋說,這是因爲只有聯盟中的第一個元素是默認構造的。

#include <SFML/Graphics.hpp> 

class Resource 
{ 
public: 
    union 
    { 
     sf::Texture t; 
     sf::Font f; 
    }; 

    Resource(sf::Font font = sf::Font()) : f(font) 
    {           } 

    ~Resource() 
    {   } 
}; 

int main() 
{ 
    Resource font; 
    Resource tex; 

    if (!tex.t.loadFromFile("player.png")) {} //! Works great! 
     //doError 

    if (!font.f.loadFromFile("blocks.ttf")) {} //! Throws access violation. 
     //doError 

    return 0; 
} 
+0

沒有SF的定義::紋理和sf ::字體是不可能分辨出發生了什麼,但我猜測f沒有被正確構建。 – evan

+0

這些是SFML庫的一部分。它的確可以用默認的構造函數構造,就像我上面所做的那樣。 – Reborn

+0

你有沒有試過看看問題是SFML類還是你的使用?我試着用'string'和'vector'來實現你的問題,並且自己也有問題。如果您可以使用stl重新創建問題,則可以覆蓋更廣泛的受衆 –

回答

2

我猜想f是單元化的。聯盟成員的內存區域重疊,除非您另外告訴編譯器,否則只有第一個成員被初始化。

您可以自己初始化它們,可以在構造函數中使用,也可以使用placement new。

new (&f) sf::Font; 

而且,破壞工會會引起問題,因爲編譯器不知道哪個破壞成員,它需要手動完成像

f.~sf::Font(); 
+0

我在哪裏可以放入'new(&f)sf :: Font;'?在構造函數中,還是在工會本身?或者在主要功能? – Reborn

+1

在'font.f.loadF ...'之前'main'中添加'new(&font.f)sf :: Font;' – evan