我已经在C ++工作了一段时间,但我以前从未遇到过这个错误。我有一个结构(名为skew_value),它有一个初始化方法,所以一切都可以有正确的默认值(如果它有一个以上的构造函数和析构函数,我使它成为一个类而不是一个结构)。我已经验证了构造函数确实被调用(断点)。并且正确设置变量。但是一旦构造函数完成,一切都是未初始化的。
代码如下:
#ifndef _LBMOON_GRAPHICSYSTEM_SKEW_VALUE_H
#define _LBMOON_GRAPHICSYSTEM_SKEW_VALUE_H
struct skew_value
{
skew_value(float tlX=1, float tlY=0, float trX=0, float trY=0, float blX=0, float blY=0, float brX=0, float brY=0)
{
skew_value(Vector2f(tlX,tlY), Vector2f(trX,trY), Vector2f(blX,blY), Vector2f(brX,brY));
}
skew_value(Vector2f topLeft, Vector2f topRight, Vector2f bottomLeft, Vector2f bottomRight)
{
TLSkew = topLeft;
TRSkew = topRight;
BLSkew = bottomLeft;
BRSkew = bottomRight;
xScale = 1;
yScale = 1;
}
float xScale;
float yScale;
Vector2f TLSkew;
Vector2f TRSkew;
Vector2f BLSkew;
Vector2f BRSkew;
Vector2f TLOrigin;
Vector2f TROrigin;
Vector2f BLOrigin;
Vector2f BROrigin;
unsigned int TLIndex;
unsigned int TRIndex;
unsigned int BLIndex;
unsigned int BRIndex;
};
#endif
Vector2f是一个包含两个float变量的类。缩放通常是其中之一,但我将其切换为两个浮点变量来测试问题不在于Vector2f类。
您可以给出关于为何调用构造函数的任何解释,但是所有被解除初始化的变量都会很棒。无论我是否将类作为指针,都会发生这种情况。我调用哪个构造函数或者提供参数也没关系。它只是在调用构造函数后拒绝跟踪数据。
答案 0 :(得分:7)
问题是您没有使用这些值返回正在初始化的对象。您对skew_value
构造函数的调用采用float参数构造并初始化一个临时的匿名自动skew_value
对象,但不会将其复制到您应该构建的对象中,也不会对其进行修改。因此,这些变化并未反映在最终返回的对象中。
C ++不是Java或C#,您可以通过这种方式本地调用嵌套构造函数(来自函数体)。
<强>然而... 强>
C ++ 11引入了这种能力;你只是没有使用正确的语法。它应该像初始化列表参数一样调用。
你应该说:
struct skew_value
{
skew_value( float tlX=1, float tlY=0, float trX=0,
float trY=0, float blX=0, float blY=0,
float brX=0, float brY=0)
: skew_value( Vector2f( tlX, tlY ),
Vector2f( trX, trY ),
Vector2f( blX, blY ),
Vector2f( brX, brY ) )
{
}
skew_value(Vector2f topLeft, Vector2f topRight,
Vector2f bottomLeft, Vector2f bottomRight)
{
TLSkew = topLeft;
TRSkew = topRight;
BLSkew = bottomLeft;
BRSkew = bottomRight;
xScale = 1;
yScale = 1;
}
....
}
IF C ++ 11功能无法使用
然后你必须做很长时间,并建议使用初始化列表来初始化你的所有值。
其他参考
在此相关问题中查找更多可能与以下内容重复的问题:Can I call a constructor from another constructor (do constructor chaining) in C++?
答案 1 :(得分:0)
在此代码中,
skew_value(float tlX=1, float tlY=0, float trX=0, float trY=0, float blX=0, float blY=0, float brX=0, float brY=0)
{
skew_value(Vector2f(tlX,tlY), Vector2f(trX,trY), Vector2f(blX,blY), Vector2f(brX,brY));
}
中间的构造函数调用正在创建临时并初始化它。
C ++ 11确实支持构造函数转发,但它有不同的语法,我从来没有使用它,你的编译器可能不一定支持它。
相反,我建议您使用基类构造函数或对象工厂函数。我不会使用init
方法,因为有充分的理由不这样做(Bjarne在他的第3版“C ++编程语言”的例外安全附录中讨论了一些)。但最终可能就是你最终会做的事情,并且在你开始要求客户端代码来调用它之前并没有那么危险。
请注意,您要离开成员变量TLIndex
,TRIndex
,BLIndex
和BRIndex
未初始化。这意味着他们将拥有不确定的值。对于一些编译器和选项,这些值将为0,但对于其他编译器和选项,它们将显然是任意的,并且很容易成为错误的来源。
还要注意预处理器符号
_LBMOON_GRAPHICSYSTEM_SKEW_VALUE_H
无效。所有使用下划线后跟大写字母的名称都保留给实现。包含两个后续下划线的名称也是如此。
在这种情况下,我怀疑你会得到任何无意的文本替换或重新定义效果,但真正有悖常理的编译器可能会将此视为错误,无论如何,这是一个最好纠正的坏习惯。 ; - )