标签:未初始化的数值
首先考虑一个具有几个构造函数的MyClass类。假设我们决定在这个类的私有部分添加一个新的数据成员,称为int_data_:
class MyClass { public: MyClass() : int_data_(0) {} explicit MyClass(const Apple& apple) : int_data_(0) {} MyClass(const string& some_text,double weight) :int_data_(0),some_text_(some_text) {} private: int int_data_; std::string some_text_; };
首先我们讨论下这个问题是与内置类型有关的。观察std::string类型的数据成员some_text_。当我们向MyClass类添加数据成员some_text_时,并不需要在MyClass类的每个构造函数中对它进行初始化,因为std::string的默认构造函数将会被编译器自动调用,把some_text_初始化为一个可重复的状态(此例中为空字符串)。但是内置类型并没有构造函数,我们应该怎么办呢?其实很简单,对于类的数据成员,不要使用内置类型,而是使用类,如下:
template <typename T> class TNumber { public: TNumber(const T& x=0) : data_(x) {} operator T () const { return data_; } TNumber& operator = (const T& x) { data_ = x; return *this; } //后缀操作符x++ TNumber operator ++ (int) { TNumber<T> copy(*this); ++data_; return copy; } //前缀操作符++x TNumber& operator ++ () { ++data_; return *this; } TNumber& operator += (T x) { data_ += x; return *this; } TNumber& operator 0= (T x) { data_ 0= x; return *this; } TNumber& operator *= (T x) { data_ *= x; return *this; } TNumber& operator /= (T x) { SCPP_TEST_ASSERT(x!=0,"Attept to divide by 0"); data_ /= x; return *this; } T operator / (T x) { SCPP_TEST_ASSERT(x!=0,"Attept to divide by 0"); return data_ / x; } private: T data_; };
以下是我们可以使用的实际类型的定义:
<span style="font-size:18px;">typedef TNumber<int> Int; typedef TNumber<unsigned> Unsigned; typedef TNumber<int64> Int64; typedef TNumber<unsigned64> Unsigned64; typedef TNumber<float> Float; typedef TNumber<double> Double; typedef TNumber<char> Char;</span>
class MyClass { public: MyClass() {} explicit MyClass(const Apple& apple) {} MyClass(const string& some_text,double weight) :some_text_(some_text) {} private: Int int_data_; std::string some_text_; };
实际上还有一个区别:当我们使用内置类型时,试图将它除零可能导致不同的结果,具体取决于编译器和操作系统。为了保持一致,这个运行时错误将导致调用与处理其他错误相同的错误处理函数,使我们可以对错误进行调试。
健壮的代码不应该在变量被初始化之前引用它们。但是,如果确实发生了这种情况,让未初始化的变量具有一个像零这样的安全值,显然要比具有随机的垃圾值好得多。
初始化的数值(int、double等),布布扣,bubuko.com
标签:未初始化的数值
原文地址:http://blog.csdn.net/kerry0071/article/details/37728645