我在玩一些模板基礎代碼的參考。出於好奇,我想知道編譯器是否以某種方式優化了我在幕後的引用(因爲每次引用都與父類中的變量相同)。我決定一個簡單的sizeof()測試會告訴我。令我非常吃驚的是,僅僅引用了我繼承的類的3個float成員,將我的類內存佔用量提高了333%。這讓我大吃一驚,困惑不已。成員引用是否填充類?或者他們只是大於非會員參考?
經過一番搗鼓之後,我甚至不知道發生了什麼事情(但我懷疑我是啞巴)。
代碼:(代碼中:: Blocks的13.12使用GCC 4.8.2在Ubuntu 14.04編譯)
#include <iostream>
template <typename T, unsigned int N>
class FooArray{
public:
FooArray(){
for (size_t i = 0; i < N; ++i)
{
m_data[i] = static_cast<T>(0);
}
}
FooArray(const T& _krv){
for (size_t i = 0; i < N; ++i)
{
m_data[i] = _krv;
}
}
T& operator[](unsigned int _index);
private:
T m_data[N];
};
template <typename T, unsigned int N>
T&
FooArray<T, N>::operator[](unsigned int _index)
{
return m_data[_index];
}
class Inherit0Ref : public FooArray<float, 3>{};
class Inherit1Ref : public FooArray<float, 3>
{
public:
Inherit1Ref():a((*this)[0]){}
float& a;
};
class Inherit2Ref : public FooArray<float, 3>
{
public:
Inherit2Ref():a((*this)[0]), b((*this)[1]){}
float& a;
float& b;
};
class Inherit3Ref : public FooArray<float, 3>
{
public:
Inherit3Ref():a((*this)[0]), b((*this)[1]), c((*this)[2]){}
float& a;
float& b;
float& c;
};
class Inherit2RefMul : public FooArray<float, 3>
{
public:
Inherit2RefMul():a((*this)[0]), b((*this)[1]){}
float& a, b;
};
class Inherit3RefMul : public FooArray<float, 3>
{
public:
Inherit3RefMul():a((*this)[0]), b((*this)[1]), c((*this)[2]){}
float& a, b, c;
};
class FloatRef
{
public:
FloatRef(float& _r):a(_r){}
float& a;
};
class WrapFloat
{
float pad;
};
class PadFloatRef
{
public:
PadFloatRef():a(pad), pad(0.0f){}
float& a;
float pad;
};
int main()
{
Inherit3Ref test;
test.a = 1.0f;
test.b = 2.0f;
test.c = 3.14f;
std::cout << test[0] << ", " << test[1] << ", " << test[2] << std::endl;
std::cout << "float size: " << sizeof(float) << std::endl;
std::cout << "float& size: " << sizeof(float&) << std::endl;
std::cout << "FloatRef size: " << sizeof(FloatRef) << std::endl;
std::cout << "WrapFloat size: " << sizeof(WrapFloat) << std::endl;
std::cout << "PadFloatRef size: " << sizeof(PadFloatRef) << std::endl;
std::cout << "FooArray<float, 3> size: " << sizeof(FooArray<float, 3>) << std::endl;
std::cout << "Inherit0Ref size: " << sizeof(Inherit0Ref) << std::endl;
std::cout << "Inherit1Ref size: " << sizeof(Inherit1Ref) << std::endl;
std::cout << "Inherit2Ref size: " << sizeof(Inherit2Ref) << std::endl;
std::cout << "Inherit3Ref size: " << sizeof(Inherit3Ref) << std::endl;
std::cout << "Inherit2RefMul size: " << sizeof(Inherit2RefMul) << std::endl;
std::cout << "Inherit3RefMul size: " << sizeof(Inherit3RefMul) << std::endl;
// Supposedly size 32, lets test assignment and access.
Inherit3RefMul testvar;
testvar.a = 5.0f;
testvar.b = 4.0f;
testvar.c = 3.142f;
// Interesting...
// testvar: 5, 0, 0
std::cout << "testvar: " << testvar[0] << ", " << testvar[1] << ", " << testvar[2] << std::endl;
return 0;
}
輸出:
1, 2, 3.14
float size: 4
float& size: 4
FloatRef size: 8
WrapFloat size: 4
PadFloatRef size: 16
FooArray<float, 3> size: 12
Inherit0Ref size: 12
Inherit1Ref size: 24
Inherit2Ref size: 32
Inherit3Ref size: 40
Inherit2RefMul size: 32
Inherit3RefMul size: 32
testvar: 5, 0, 0
很好奇。 :) 爲什麼包裹浮動引用(FloatRef)是包裹浮動(WrapFloat)大小的兩倍? 爲什麼使用一個浮點引用關鍵字(Inherit3RefMul)聲明3浮點引用會產生與具有2個引用而不是3(Inherit2Ref)的同一類相同的腳印? 爲什麼只有TestVar的第一個變量被填充,而所有3個測試都按預期填充? 有沒有一種方法來實現Inherit3Ref的功能,而沒有可笑的內存佔用40?
編輯:
請注意:
sizeof(float&) == 4
更新:
運行alignof(float&)
返回4.我沒有看到一個浮動的原因[3]浮動& [3 ]類的大小爲40,當所有變量的大小爲4並且對齊爲4.
感謝您參考聲明說明,我沒有意識到這種方式的語法。但是,請注意'sizeof(float&)'返回4.經過測試,'alignof(float&)'也返回4.這是否僅僅是我的另一個編程錯誤?看起來奇怪的是,包裝參考大小4使得課程大小爲8,而包裝浮動大小4則留下課程大小4. – Alterior 2014-10-29 02:17:10
'sizeof(float&)'不會給你參考的大小,但大小提到的對象。引用是奇怪的野獸,幾乎總是衰減到所提到的類型。嘗試'sizeof(std :: reference_wrapper)'來獲取引用的實際大小。 –
Walter
2014-10-29 09:57:47
哇,這是一個很酷的類型...我喜歡標準庫!非常感謝你的幫助@沃爾特。 – Alterior 2014-10-29 12:23:16