各位好小弟遇到一個問題過去我們設計了一些圖形用的數學運算類別,其中透過 union 來實現資料的異名
class CMatrix4FLOAT {
public:
union{
struct { float m_Buffer[16]; };
struct { float _M00, _M10, _M20, _M30,
_M01, _M11, _M21, _M31,
_M02, _M12, _M22, _M32,
_M03, _M13, _M23, _M33; };
}
...
...
};
或是
class CVectorReference4FLOAT {
public:
union{
struct { float &m_x, &m_y, &m_z, &m_w; };
struct { float &m_s, &m_t, &m_p, &m_q; };
struct { float &m_r, &m_g, &m_b, &m_a; };
}
....
....
};
問題來了在 VS2015 後 C11 不允許在 union 中使用參考,請問有別的方法實現資料的異名? 或是我只能被逼著改用指標?
uj5u.com熱心網友回復:
這個,你可以在類物件級別使用別名啊。不要在類成員里面別名,直接物件別名,有困難嗎?別名就是你說的異名,指標就是你說的指標。uj5u.com熱心網友回復:
你要用匿名聯合體,給聯合體加個名字。(結構體也一樣)uj5u.com熱心網友回復:
由於這是配合計算機圖學的情境設計的物件 CVectorReference4FLOAT 可以說是種容器
根據使用的情境同一個位置的資料會出現不同的意思
float Buffer[4];
CVectorReference4FLOAT P0(Buffer);
CVectorReference4FLOAT Color(Buffer);
CVectorReference4FLOAT Coordinate(Buffer);
P0.Set(5.0f, 3.0f, -1.0f, 1.0f);
P0.m_x = 5.0f; P0.m_y = 5.0f; P0.m_z = 5.0f;
Color.Set(0.3f, 0.5f, 0.2f, 1.0f);
Color.m_r = 1.0; Color.m_g = 1.0; Color.m_b = 1.0;
這樣很好讀語意很清晰,這是配合 GLSL 設計的
uj5u.com熱心網友回復:
聯合體(或結構體)的成員如果不用&參考,貌似加建構式就可以,如果用&參考,聯合體(或結構體)要用指標或者也要加建構式。
比如
class SV16 {
public:
union{
struct { float m_Buffer[16]; };
struct { float _M00, _M10, _M20, _M30,
_M01, _M11, _M21, _M31,
_M02, _M12, _M22, _M32,
_M03, _M13, _M23, _M33; };
};
SV16() {} //加建構式
SV16(float buff[16]) {memcpy(m_Buffer, buff, 16);}
};
int main() {
float buff1[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
SV16 sv16(buff1);
printf("%f\n", sv16._M00);
return 0;
}
uj5u.com熱心網友回復:
用物件參考完全可以達到你的目的啊
float Buffer[4];
CVectorReference4FLOAT P0(Buffer); // 類里面有16個float你這里只有4個,能正常初始化嗎?
CVectorReference4FLOAT &Color = P0;
CVectorReference4FLOAT &Coordinate = P0;
P0.Set(5.0f, 3.0f, -1.0f, 1.0f);
P0.m_x = 5.0f; P0.m_y = 5.0f; P0.m_z = 5.0f;
Color.Set(0.3f, 0.5f, 0.2f, 1.0f);
Color.m_r = 1.0; Color.m_g = 1.0; Color.m_b = 1.0;
uj5u.com熱心網友回復:
聯合體(或結構體)的成員如果不用&參考,貌似加建構式就可以,如果用&參考,聯合體(或結構體)要用指標或者也要加建構式。
比如
class SV16 {
public:
union{
struct { float m_Buffer[16]; };
struct { float _M00, _M10, _M20, _M30,
_M01, _M11, _M21, _M31,
_M02, _M12, _M22, _M32,
_M03, _M13, _M23, _M33; };
};
SV16() {} //加建構式
SV16(float buff[16]) {memcpy(m_Buffer, buff, 16);}
};
int main() {
float buff1[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
SV16 sv16(buff1);
printf("%f\n", sv16._M00);
return 0;
}
是的矩陣方面目前沒有甚麼問題,我們過去在 VS2008 已經實現了,參考 的部分使用預先建構式
CVectorReference4FLOAT::CVectorReference4FLOAT( float & Value0, float & Value1, float & Value2, float & Value3 ):
m_x(Value0),m_y(Value1),m_z(Value2),m_w(Value3),
m_s(Value0),m_t(Value1),m_p(Value2),m_q(Value3),
m_r(Value0),m_g(Value1),m_b(Value2),m_a(Value3)
{
}
但是隨著編譯器改版到 VS2015 之後的 C11 編譯器並不允許在 union 中 使用參考了,我沒辦法簡單的用不同的名字去表示同一個資料欄位,像這樣都是同一個欄位的資料
P0.m_x = 5.0f
P0.m_r = 5.0f
如果退回使用指標就會像
(*P0.m_x) = 5.0f
(*P0.m_r) = 5.0f
偏偏這還是個數學運算用途可能帶有大量的 *
float length = sqrtf( *m_x * *m_x + *m_y * *m_y + *m_z * *m_z);
uj5u.com熱心網友回復:
用物件參考完全可以達到你的目的啊
float Buffer[4];
CVectorReference4FLOAT P0(Buffer); // 類里面有16個float你這里只有4個,能正常初始化嗎?
CVectorReference4FLOAT &Color = P0;
CVectorReference4FLOAT &Coordinate = P0;
P0.Set(5.0f, 3.0f, -1.0f, 1.0f);
P0.m_x = 5.0f; P0.m_y = 5.0f; P0.m_z = 5.0f;
Color.Set(0.3f, 0.5f, 0.2f, 1.0f);
Color.m_r = 1.0; Color.m_g = 1.0; Color.m_b = 1.0;
我們的問題是 VS2015 以後的 C11 編譯器不能在 union 中使用 參考 所以就不能可能出現
P0.m_x = 5.0f;
Color.m_r = 1.0;
你會變成必須使用兩個不同參考去指向同一個記憶體位址 而不是 兩個參考共用同一塊記憶體位址,這樣的話 使用 資料異名 記憶體使用量就會加倍
union{
struct { float &m_x, &m_y, &m_z, &m_w; };
struct { float &m_s, &m_t, &m_p, &m_q; };
struct { float &m_r, &m_g, &m_b, &m_a; };
}
原來的情況是 12 個參考共用 4 個參考的空間,m_x m_s m_r 都使用同一塊記憶體 而不是三份的記憶體
uj5u.com熱心網友回復:
struct { float &m_x, &m_y, &m_z, &m_w; };struct {float[4] dat} object;
union A
{
r = 0,
g,
b,
a,
s = 0,
t,
p,
q,
x = 0,
y,
z,
w,
}
如果union不允許使用的話,那么這樣勉強能用?作為下標object.dat[A]
-------------------------------------------------------------------------------------
說不定還有更好的方式,暫時還沒想到
uj5u.com熱心網友回復:
struct { float &m_x, &m_y, &m_z, &m_w; };
struct {float[4] dat} object;
union A
{
r = 0,
g,
b,
a,
s = 0,
t,
p,
q,
x = 0,
y,
z,
w,
}
如果union不允許使用的話,那么這樣勉強能用?作為下標object.dat[A]
-------------------------------------------------------------------------------------
說不定還有更好的方式,暫時還沒想到
object.dat[r]==object.dat[s]==object.dat[x]
...
uj5u.com熱心網友回復:
struct { float &m_x, &m_y, &m_z, &m_w; };
struct {float[4] dat} object;
union A
{
r = 0,
g,
b,
a,
s = 0,
t,
p,
q,
x = 0,
y,
z,
w,
}
如果union不允許使用的話,那么這樣勉強能用?作為下標object.dat[A]
-------------------------------------------------------------------------------------
說不定還有更好的方式,暫時還沒想到
object.dat[r]==object.dat[s]==object.dat[x]
...
再好看點就在封一層函式
float getdata(A a)
{
//安全性檢查,不知道有沒有
return object.dat[a];
}
uj5u.com熱心網友回復:
我們的問題是 VS2015 以後的 C11 編譯器不能在 union 中使用 參考 所以就不能可能出現
P0.m_x = 5.0f;
Color.m_r = 1.0;
你會變成必須使用兩個不同參考去指向同一個記憶體位址 而不是 兩個參考共用同一塊記憶體位址,這樣的話 使用 資料異名 記憶體使用量就會加倍
union{
struct { float &m_x, &m_y, &m_z, &m_w; };
struct { float &m_s, &m_t, &m_p, &m_q; };
struct { float &m_r, &m_g, &m_b, &m_a; };
}
原來的情況是 12 個參考共用 4 個參考的空間,m_x m_s m_r 都使用同一塊記憶體 而不是三份的記憶體
暫時想不到太好的辦法。因為參考不占用記憶體空間。即使你換成指標,這個類的sizeof也比原來的大。
uj5u.com熱心網友回復:
是的矩陣方面目前沒有甚麼問題,我們過去在 VS2008 已經實現了,參考 的部分使用預先建構式
但是隨著編譯器改版到 VS2015 之後的 C11 編譯器並不允許在 union 中 使用參考了,我沒辦法簡單的用不同的名字去表示同一個資料欄位,像這樣都是同一個欄位的資料
P0.m_x = 5.0f
P0.m_r = 5.0f
如果退回使用指標就會像
(*P0.m_x) = 5.0f
(*P0.m_r) = 5.0f
偏偏這還是個數學運算用途可能帶有大量的 *
float length = sqrtf( *m_x * *m_x + *m_y * *m_y + *m_z * *m_z);
改成指標的方式好像可以
比如
class SV16 {
public:
union{
struct { float m_Buffer[16]; };
struct { float _M00, _M10, _M20, _M30,
_M01, _M11, _M21, _M31,
_M02, _M12, _M22, _M32,
_M03, _M13, _M23, _M33; };
};
SV16() {}
SV16(float buff[16]) {memcpy(m_Buffer, buff, 16);}
};
class SV4 {
public:
union{
struct { float *m_0, *m_1, *m_2, *m_3; };
struct { float &m_x, &m_y, &m_z, &m_w; };
struct { float &m_s, &m_t, &m_p, &m_q; };
struct { float &m_r, &m_g, &m_b, &m_a; };
};
SV4() {}
SV4(float buff[4]) {
m_0 = &buff[0];
m_1 = &buff[1];
m_2 = &buff[2];
m_3 = &buff[3];
}
};
int main() {
float buff1[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
float buff2[4]={2,4,6,8};
SV16 sv16(buff1);
SV4 sv4(buff2);
printf("%f\n", sv16._M00);
printf("%f, %f, %f, %f\n", sv4.m_s, sv4.m_y, sv4.m_b, *sv4.m_3);
printf("%d,%d\n", (int)sizeof(sv16), (int)sizeof(sv4));
sv4.m_x = 5;
printf("%f, %f\n", sv4.m_s, buff2[0]);
return 0;
}
uj5u.com熱心網友回復:
改成指標的方式好像可以
是可以但是不好讀還很容易錯,很想給 C++ 發展委員會兩巴掌,淨幹一些扯後腿的事情,整天在哪搞 STL 搞得越來越複雜,原來 C++ 簡潔的美感都沒有了還跟不上時代,怪不得佔有率直線下滑
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/69219.html
標籤:C++ 語言
上一篇:c語言問題求解
下一篇:新手求解答c++中的鏈表問題
