检查一个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) {}
上面构造函数中的初始化列表值 – 初始化您的数据成员为零。 您现在可以正确地假设mCharacter
和mDecimal
任何非零值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; }