2013-02-25 118 views
-8

目前工作在我的DirectX的遊戲,用memset(0)(或VS ZeroMemory宏,如果你願意的話)在不斷的緩衝構造函數初始化用零所有值和它工作得很好。當我不小心嘗試用這種方法初始化其他包含矢量的工具時,就會出現問題。根據編譯器(VS2010/VS2012),這導致「向量迭代器不兼容」,std :: vector :: end更加精確。我可以理解,memset可能會使矢量迭代器失效,但爲什麼在將元素推回到矢量後,「end」迭代器無法正常工作。它不應該重新定位向量結束迭代器到正確的位置(在最後一個元素之後)嗎?是否所有類型的std :: some_container :: end迭代器都受此影響?memset的原因「矢量迭代器不兼容」的錯誤

#include <vector> 

class MyClass 
{ 
public: 
    MyClass() { 
     memset(this, 0, sizeof(*this)); 
    } 
    ~MyClass() {} 
    std::vector<int>& GetData() { return m_data; } 
    float   m_range; 
private: 
    std::vector<int> m_data; 

}; 

int main() 
{ 
    MyClass myClass; 
    myClass.GetData().push_back(1); 
    myClass.GetData().push_back(2); 

    for (auto it = myClass.GetData().begin(); it != myClass.GetData().end(); it++)  
    { 
     //stuff 
    } 
} 
+6

只是...不要...使用... memset。它...只是工作... – 2013-02-25 13:24:21

+0

那麼不要使用'memset'問題解決。這不是火箭科學。 – 2013-02-25 13:24:27

+1

你究竟想要在構造函數中對'* this'做一個memset?這是可怕的。 – 2013-02-25 13:24:30

回答

3

你不應該是memset任何具有構造函數的類的對象。

+3

你不應該用C使用'memset'都++。 – 2013-02-25 13:25:01

+0

@Zoidberg它有它的用途;但這當然不是一個。 – 111111 2013-02-25 13:26:09

+0

@Zoidberg,但你不能:)。只要看看你的標準庫頭文件。 – 2013-02-25 13:27:04

2

而是執行此操作:

class MyClass { 
public: 
    MyClass() : range{} { 

    } 

    float range; 
    std::vector<int> data; 
}; 

切勿使用memset,當然絕對不是this哦,上帝。

臨提示:buy a good book

+2

@MaximYegorushkin:它有,'float'將被保留爲未初始化。 – Xeo 2013-02-25 13:28:34

7

std::vector已經有一個正確初始化向量默認構造函數。無所事事有你想要的行爲。使用memset只是有未定義的行爲。

如果你想在float成員初始化爲零,C++提供了與類似的代碼如下:

MyClass() : m_range(0) {} 

C++ 11也允許寫float m_range = 0;,但微軟的編譯器沒有實現此功能尚未。

mem*函數是非常粗糙的工具,在C++構造中沒有地方,如std::vector。像正確的初始化,std::copystd::fill等替代方案是優越的解決方案,因爲它們不會踐踏類型系統。

0

你的對象是導致問題的memset之前建造。

以這種方式初始化對象在C++中不是一個好方法