C++ 在初始化对象之前在对象上运行的方法? #包括 使用名称空间std; 福班 { 公众: Foo():已初始化(0) { cout
是的,它是在一个尚未构造的对象上调用函数,这是一种未定义的行为。您无法可靠地检测到它。我认为您也不应该尝试检测它。与在一个已删除的对象上调用函数相比,这并不是偶然发生的事情。尝试捕获所有可能的mISTACK几乎是不可能的。声明的名称在其初始化器中已经可见,用于其他有用的目的。C++ 在初始化对象之前在对象上运行的方法? #包括 使用名称空间std; 福班 { 公众: Foo():已初始化(0) { cout,c++,initialization,C++,Initialization,是的,它是在一个尚未构造的对象上调用函数,这是一种未定义的行为。您无法可靠地检测到它。我认为您也不应该尝试检测它。与在一个已删除的对象上调用函数相比,这并不是偶然发生的事情。尝试捕获所有可能的mISTACK几乎是不可能的。声明的名称在其初始化器中已经可见,用于其他有用的目的。 #include <iostream> using namespace std; class Foo { public: Foo(): initialised(0) { cout <<
#include <iostream>
using namespace std;
class Foo
{
public:
Foo(): initialised(0)
{
cout << "Foo() gets called AFTER test() ?!" << endl;
};
Foo test()
{
cout << "initialised= " << initialised << " ?! - ";
cout << "but I expect it to be 0 from the 'initialised(0)' initialiser on Foo()" << endl;
cout << "this method test() is clearly working on an uninitialised object ?!" << endl;
return Foo();
}
~Foo()
{};
private:
int initialised;
};
int main()
{
//SURE this is bad coding but it compiles and runs
//I want my class to DETECT and THROW an error to prevent this type of coding
//in other words how to catch it at run time and throw "not initialised" or something
Foo foo=foo.test();
}
是C语言编程中常用的一个习语,它仍然在C++中工作。 就个人而言,我喜欢Herb Sutter关于空引用(同样无效)的文章。要点是,不要试图避免语言明确禁止的情况,尤其是在一般情况下无法可靠诊断的情况。随着时间的推移,您将获得错误的安全性,这将变得非常危险。相反,应以某种方式培训您对语言和设计接口的理解(避免原始指针,…)这减少了犯错误的机会
<>在C++中,同样地,在C中,很多情况并没有明确禁止,而是没有定义。部分原因是一些事情很难有效地诊断,部分是因为未定义的行为允许实现设计替代行为,而不是完全忽略它——这通常被现有的COMPI使用。莱勒斯例如,在上面的例子中,任何实现都可以自由抛出异常。还有其他一些情况同样是未定义的行为,对于实现来说更难有效地诊断:在构建不同转换单元中的对象之前访问它就是这样一个例子,这就是所谓的static初始化命令失败。是的,它正在对尚未构造的对象调用函数,这是未定义的行为。您无法可靠地检测到它。我认为您也不应该尝试检测它。与对已删除的对象调用函数相比,这并不是偶然发生的。尝试捕获每一个可能发生的错误几乎是不可能的。声明的名称在其初始化器中已经可见,用于其他有用的目的。请考虑:
#include <iostream>
using namespace std;
class Foo
{
public:
Foo(): initialised(0)
{
cout << "Foo() gets called AFTER test() ?!" << endl;
};
Foo test()
{
cout << "initialised= " << initialised << " ?! - ";
cout << "but I expect it to be 0 from the 'initialised(0)' initialiser on Foo()" << endl;
cout << "this method test() is clearly working on an uninitialised object ?!" << endl;
return Foo();
}
~Foo()
{};
private:
int initialised;
};
int main()
{
//SURE this is bad coding but it compiles and runs
//I want my class to DETECT and THROW an error to prevent this type of coding
//in other words how to catch it at run time and throw "not initialised" or something
Foo foo=foo.test();
}
是C语言编程中常用的一个习语,它仍然在C++中工作。 就个人而言,我喜欢Herb Sutter关于空引用(同样无效)的文章。要点是,不要试图避免语言明确禁止的情况,尤其是在一般情况下无法可靠诊断的情况。随着时间的推移,您将获得错误的安全性,这将变得非常危险。相反,应以某种方式培训您对语言和设计接口的理解(避免原始指针,…)这减少了犯错误的机会
<>在C++中,同样地,在C中,很多情况并没有明确禁止,而是没有定义。部分原因是一些事情很难有效地诊断,部分是因为未定义的行为允许实现设计替代行为,而不是完全忽略它——这通常被现有的COMPI使用。莱勒斯例如,在上面的例子中,任何实现都可以自由抛出异常。还有其他一些情况同样是未定义的行为,对于实现来说更难有效地诊断:在构建不同转换单元中的对象之前访问它就是这样一个例子,这就是所谓的static初始化顺序失败。构造函数是您想要的方法(不是在初始化之前运行,而是在初始化时运行,但这应该可以)。在您的情况下,它不起作用的原因是您在这里有未定义的行为 特别是,您可以使用尚未存在的foo对象来初始化自身(例如
foo.Test()
中的foo
还不存在)。您可以通过显式创建对象来解决此问题:
Type *t = (Type*)malloc(sizeof(*t));
您无法在程序中检查它,但valgrind可能会发现这种类型的错误(与任何其他未初始化的内存访问一样)。构造函数是您想要的方法(不是在初始化之前运行,而是在初始化时运行,但这应该可以).它在你的情况下不起作用的原因是你在这里有未定义的行为 特别是,您可以使用尚未存在的foo对象来初始化自身(例如
foo.Test()
中的foo
还不存在)。您可以通过显式创建对象来解决此问题:
Type *t = (Type*)malloc(sizeof(*t));
您无法在程序中检查它,但valgrind可能会发现这种类型的错误(与任何其他未初始化的内存访问一样)。您无法阻止人们编写糟糕的代码。它的工作原理与“应该”一样:
就像它应该。你不能阻止人们不知道正确使用C++的方式。
你能做的最好的事情就是有一个神奇的数字:Foo foo=Foo().test()
这“起作用”是因为在值已经为1337的地方分配magicFlag的机会很低
但真的,不要这样做。你不能阻止人们编写糟糕的代码,真的。它的工作原理就像“应该”一样: