检查一个variables是否被初始化

似乎这将是一个重复,但也许它是如此明显,它没有被问到…

这是检查一个variables(而不是指针)是否在C ++类中初始化的正确方法?

class MyClass { void SomeMethod(); char mCharacter; double mDecimal; }; void MyClass::SomeMethod() { if ( mCharacter ) { // do something with mCharacter. } if ( ! mDecimal ) { // define mDecimal. } } 

没有办法检查一个variables的内容是不是未定义的。 你可以做的最好的事情是分配一个信号/哨兵值(例如在构造函数中)来表示需要进一步的初始化。

未定义的variables将导致编译错误。

你要问的是检查它是否被初始化 。 但是初始化只是一个值,你应该在构造函数中select和赋值。

例如:

 class MyClass { MyClass() : mCharacter('0'), mDecimal(-1.0){}; void SomeMethod(); char mCharacter; double mDecimal; }; void MyClass::SomeMethod() { if ( mCharacter != '0') { // touched after the constructor // do something with mCharacter. } if ( mDecimal != -1.0 ) { // touched after the constructor // define mDecimal. } } 

当然,你应该初始化为一个默认值,这个默认值在你的逻辑上下文中是有意义的。

根据您的应用程序(尤其是如果您已经使用boost),您可能需要查看boost::optional

http://www.boost.org/doc/libs/1_47_0/libs/optional/doc/html/index.html

它有你正在寻找的财产,追踪插槽实际上是否有价值。 默认情况下,它被构造成不保存一个值并计算为false,但是如果计算结果为true,则允许对其进行解引用并获取包装的值。

 class MyClass { void SomeMethod(); optional<char> mCharacter; optional<double> mDecimal; }; void MyClass::SomeMethod() { if ( mCharacter ) { // do something with *mCharacter. // (note you must use the dereference operator) } if ( ! mDecimal ) { // call mDecimal.reset(expression) // (this is how you assign an optional) } } 

文档中有更多的例子。

http://www.boost.org/doc/libs/1_47_0/libs/optional/doc/html/boost_optional/examples.html

默认情况下,不,你不知道一个variables(或指针)是否已经被初始化。 然而,由于其他人都在告诉你“简单”或“正常”的方法,所以我会给你别的想法。 下面是你如何跟踪这样的事情(不,我个人不会这样做,但也许你有不同的需求比我)。

 class MyVeryCoolInteger { public: MyVeryCoolInteger() : m_initialized(false) {} MyVeryCoolInteger& operator=(const int integer) { m_initialized = true; m_int = integer; return *this; } int value() { return m_int; } bool isInitialized() { return m_initialized; } private: int m_int; bool m_initialized; }; 

如果你的意思是如何检查成员variables是否被初始化,你可以通过在构造函数中指定它们的标记值来完成。 select哨兵值作为在该variables的正常使用中永远不会发生的值。 如果一个variables的整个范围被认为是有效的,你可以创build一个布尔值来指示它是否已经被初始化。

 #include <limits> class MyClass { void SomeMethod(); char mCharacter; bool isCharacterInitialized; double mDecimal; MyClass() : isCharacterInitialized(false) , mDecimal( std::numeric_limits<double>::quiet_NaN() ) {} }; void MyClass::SomeMethod() { if ( isCharacterInitialized == false ) { // do something with mCharacter. } if ( mDecimal != mDecimal ) // if true, mDecimal == NaN { // define mDecimal. } } 

由于MyClass是POD类的types,当你创buildMyClass的非静态实例时,这些非静态数据成员将具有不确定的初始值,所以不,这不是检查它们是否被初始化为特定的非 – 零值…你基本上假设它们将被初始化为零,这不会是事实,因为你没有在构造函数中初始化它们。

如果你想零初始化你的类的非静态数据成员,最好是创build一个初始化列表和类构造函数。 例如:

 class MyClass { void SomeMethod(); char mCharacter; double mDecimal; public: MyClass(); }; MyClass::MyClass(): mCharacter(0), mDecimal(0) {} 

上面构造函数中的初始化列表值 – 初始化您的数据成员为零。 您现在可以正确地假设mCharactermDecimal任何非零值mDecimal必须由代码中的其他位置专门设置,并且包含可以正确执行的非零值。

没有合理的方法来检查一个值是否已被初始化。

如果你关心是否已经初始化了一些东西,而不是试图去检查它,那就把代码放到构造器中,以确保它们总是被初始化并且被完成。

使用C ++ – 11,您可以考虑使用智能指针来存储variables。 考虑这个MVE,其中的toString()行为取决于被初始化的bar

 #include <memory> #include <sstream> class Foo { private: std::shared_ptr<int> bar; public: Foo() {} void setBar(int bar) { this->bar = std::make_shared<int>(bar); } std::string toString() const { std::ostringstream ss; if (bar) // bar was set ss << *bar; else // bar was never set ss << "unset"; return ss.str(); } }; 

使用这个代码

 Foo f; std::cout << f.toString() << std::endl; f.setBar(42); std::cout << f.toString() << std::endl; 

产生输出

 unset 42 

C ++语言没有办法检查variables是否被初始化(尽pipe具有构造函数的类types将被自动初始化)。

相反,你需要做的是提供构造函数来初始化你的类到一个有效的状态。 静态代码检查器(可能还有一些编译器)可以帮助您在构造函数中find缺less的variables。 这样你就不必担心处于一个假的状态, if你的方法检查可以完全消失。

如果你使用string,而不是字符,你可能会做这样的事情:

  //a is a string of length 1 string a; //b is the char in which we'll put the char stored in a char b; bool isInitialized(){ if(a.length() != NULL){ b = a[0]; return true; }else return false; }