Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将Vec*转换为双精度*_C++_Arrays_Casting - Fatal编程技术网

C++ 将Vec*转换为双精度*

C++ 将Vec*转换为双精度*,c++,arrays,casting,C++,Arrays,Casting,我试图理解一个框架,并慢慢地调试它。在我的例子中,我有一个向量数组,用指针存储: Vec *cx =....; My Vec是一个定义如下的结构: struct Vec { double x, y, z; // position, also color (r,g,b) Vec(double x_ = 0, double y_ = 0, double z_ = 0){ x = x_; y = y_; z = z_; } Vec opera

我试图理解一个框架,并慢慢地调试它。在我的例子中,我有一个向量数组,用指针存储:

Vec *cx =....;
My Vec是一个定义如下的结构:

struct Vec {
    double x, y, z;                  // position, also color (r,g,b)
    Vec(double x_ = 0, double y_ = 0, double z_ = 0){ x = x_; y = y_; z = z_; }
    Vec operator+(const Vec &b) const { return Vec(x + b.x, y + b.y, z + b.z); }
    Vec operator-(const Vec &b) const { return Vec(x - b.x, y - b.y, z - b.z); }
    Vec operator-() const { return Vec(-x, -y, -z); }
    Vec operator*(double b) const { return Vec(x*b, y*b, z*b); }
    Vec mult(const Vec &b) const { return Vec(x*b.x, y*b.y, z*b.z); }
    Vec& norm(){ return *this = *this * (1 / sqrtf(x*x + y*y + z*z)); }
    double dot(const Vec &b) const { return x*b.x + y*b.y + z*b.z; } // cross:
    Vec operator%(Vec&b){ return Vec(y*b.z - z*b.y, z*b.x - x*b.z, x*b.y - y*b.x); }
    double max() const { return x>y && x>z ? x : y > z ? y : z; }
};
我想知道如果我把一个向量数组转换成一个双倍数组,会发生什么。实际上:

double * cast = (double*)cx;
它给了我什么

为了理解,我试着这样做:

Vec boh = Vec(1.0, 1.0, 1.0);
Vec boh2 = Vec(2.0, 2.0, 2.0);
Vec * try = new Vec[2];
try[0] = boh;
try[1] = boh2;
double* try2= (double*)try;
我意识到try指向第一个Vec,即boh1,因此如果我进行调试,我会看到x、y、z值设置为1。同样,try2应该指向与boh1相关的“某物”,但调试显示try2的值为1.000000。那么,到底发生了什么


<>编辑:“尝试”不能用作C++中变量的名称。 它仍然会给你一个指向
Vec
的指针,这根本不是一个
双精度
。强制转换所做的是告诉编译器完全忽略
try
的实际类型,实际上假装
try
不是


使用
try2
将导致未定义的行为。

它仍然会给您一个指向
Vec
的指针,这根本不是一个
双重
。强制转换所做的是告诉编译器完全忽略
try
的实际类型,实际上假装
try
不是


使用
try2
将导致未定义的行为。

程序的行为未定义


本质上,
sizeof(double)
sizeof(Vec)
不同,因此所有指针算法和数组索引都将在C样式转换后崩溃。

程序的行为未定义

本质上,
sizeof(double)
sizeof(Vec)
不同,因此所有指针算法和数组索引都会在C样式转换后崩溃。

实际发生的是,由于结构的数据成员是3个double,您的同事正在指望C行为,他们将内存视为
double
而不是
Vec
。在C语言中,它的作用类似于一个“并集”,即内存中的结构布局只有3个双倍。在您的情况下(使用C++),它就像一个工会一样(请参见编辑)。因此,您正在从
boh
(您称之为
boh1
)访问1.0。其他人说,这种行为是不明确的。我相信“依赖于实现”可能更准确,但我会遵从它们(除非我能找到参考资料)

无论如何,如果可以的话,您的代码示例已经成熟,可以进行重构了。如果你的同事依赖这种行为,他们应该清楚地识别出来,这样其他人就不会跟着改变结构

编辑:好的,我发现了一个参考,表明这不是未定义的行为(除非我误解了该参考)。结构是一个POD结构,每节9(SS7,10)的C++ + Po.Pod(普通旧数据)布局在9.2(SS13)中描述。 9 ss10
POD结构110是一个非联合类,它既是普通类又是标准布局类,并且没有非POD结构、非POD联合(或此类类型的数组)类型的非静态数据成员。类似地,POD联合是一个联合,它既是普通类又是标准布局类,并且不具有非POD结构、非POD联合(或此类类型的数组)类型的非静态数据成员。POD类是一个POD结构或POD联合的类

9 ss7
S类是标准布局类,如果:
-(7.1)没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员,
-(7.2)没有虚拟函数(10.3)和虚拟基类(10.1),
-(7.3)对所有非静态数据成员具有相同的访问控制(第11条),
-(7.4)没有非标准布局基类,
-(7.5)最多有一个给定类型的基类子对象,
-(7.6)类中的所有非静态数据成员和位字段及其基类首先在同一类中声明,以及
-(7.7)没有类型(定义如下)集合M(S)中的元素作为基类。109

9.2 ss13
具有相同访问控制(第11条)的(非联合)类的非静态数据成员被分配,以便后面的成员在类对象中具有更高的地址。具有不同访问控制的非静态数据成员的分配顺序未规定(第11条)。实施一致性要求可能会导致两个相邻的成员不能紧随其后进行分配;管理虚拟函数(10.3)和虚拟基类(10.1)的空间需求也是如此

因此,我怀疑你的同事是依靠吊舱布局来获得“联盟”式的行为。我仍然认为这是一种非常糟糕的做法。如果无法避免,则应添加编译时检查或记录结构以确定此要求。

实际发生的情况是,由于结构的数据成员是3个双倍,您的同事正在指望C行为,他们将内存视为
double
而不是
Vec
。在C语言中,它的作用类似于一个“并集”,即内存中的结构布局只有3个双倍。在您的情况下(使用C++),它就像一个工会一样(请参见编辑)。因此,您正在从
boh
(您称之为
boh1
)访问1.0。其他人说,这种行为是不明确的。我相信“依赖于实现”可能更准确,但我会遵从它们(除非我能找到参考资料)

无论如何,如果可以的话,您的代码示例已经成熟,可以进行重构了。如果你的同事依赖这种行为,他们应该清楚地识别出来,这样其他人就不会跟着改变结构