我希望有人能够准确地澄清C++中未定义行为的含义.给定以下类定义:
class Foo
{
public:
explicit Foo(int Value): m_Int(Value) { }
void SetValue(int Value) { m_Int = Value; }
private:
Foo(const Foo& rhs);
const Foo& operator=(const Foo& rhs);
private:
int m_Int;
};
Run Code Online (Sandbox Code Playgroud)
如果我已经正确理解了以下代码中的引用和指针的两个const_casts将删除Foo类型的原始对象的常量,但是通过指针或引用修改此对象的任何尝试都将导致未定义的行为.
int main()
{
const Foo MyConstFoo(0);
Foo& rFoo = const_cast<Foo&>(MyConstFoo);
Foo* pFoo = const_cast<Foo*>(&MyConstFoo);
//MyConstFoo.SetValue(1); //Error as MyConstFoo is const
rFoo.SetValue(2); //Undefined behaviour
pFoo->SetValue(3); //Undefined behaviour
return 0;
}
Run Code Online (Sandbox Code Playgroud)
让我感到困惑的是为什么这似乎有效并将修改原始的const对象,但是甚至没有提示我发出警告通知我这种行为是未定义的.从广义上讲,我知道const_casts是不受欢迎的,但是我可以想象一种情况是缺乏对C风格的强制转换可以导致const_cast的意识,而不会被注意到,例如:
Foo& rAnotherFoo = (Foo&)MyConstFoo;
Foo* pAnotherFoo = (Foo*)&MyConstFoo;
rAnotherFoo->SetValue(4);
pAnotherFoo->SetValue(5);
Run Code Online (Sandbox Code Playgroud)
在什么情况下这种行为会导致致命的运行时错误?是否有一些编译器设置可以设置为警告我这种(可能)危险的行为?
注意:我使用的是MSVC2008.
我有一个3D场景,我的3D模型被加载到XAML文件后面的代码中.
每个模型都由一组嵌套的Model3DGroups组成,每个Model3DGroups都应用了各种变换,以便在树中定位和定向模型的下一个子组件.然后将此模型用作ModelVisual3D的内容,以便可以将其显示在屏幕上.
我想将一个孩子ModelVisual3D附加到'父'ModelVisual3D.这个子ModelVisual3D需要使用父ModelVisual3D.Content的所有嵌套转换来正确定位和定位自己在虚拟空间中.例如,第一个ModelVisual3D是一个机器人手臂,它有各种可移动的关节,我想在这个手臂的末端附加一个工具 - 另一个ModelVisual3D.如何从父ModelVisual3Ds内容属性访问此复合变换,以允许我相对于其父项正确定位下一个ModelVisual3D?
考虑以下设计的模板化数组定义示例:
template <typename t, unsigned int n> class TBase
{
protected:
t m_Data[n];
//...
};
template <typename t, unsigned int n> class TDerived : public TBase<t, n>
{
TDerived()
{
}
};
Run Code Online (Sandbox Code Playgroud)
我可以专门化这种类型为长度为2的数组提供非默认构造函数,如下所示:
template <typename t> class TDerived<t, 2> : public TBase<t, 2>
{
public:
TDerived(const t& x0, const t& x1)
{
m_Data[0] = x0;
m_Data[1] = x1;
}
};
int main()
{
TDerived<float, 2> Array2D_A(2.0f, 3.0f); //uses specialised constructor
TDerived<float, 3> Array3D_A; //uses default constructor
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有没有其他方法我可以创建一个类,在编译时有不同的构造函数选项约束模板参数,而不需要为每个变体进行完整的类专门化? …
有人可以向我解释为什么在下面的代码中,如果我尝试实例化MyFooC,我会对Foo中的重载构造函数进行模糊调用吗?我的假设是用作构造函数参数的整数将被提升为unsigned int并已解决,但这显然是不正确的.
template <typename t> class Foo
{
private:
t m_Value;
unsigned int m_Length;
public:
Foo(const t& Value) :
m_Value(Value),
m_Length(0)
{
}
Foo(unsigned int Length) :
m_Value(static_cast<t>(0)),
m_Length(Length)
{
}
};
int main()
{
Foo<double> MyFooA(32U);
Foo<double> MyFooB(32.0f);
//Foo<double> MyFooC(32);
return 0;
}
Run Code Online (Sandbox Code Playgroud)