首先考虑一个具有几个构造函数的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_;
};

加入这个新的数据成员时。须要做大量的工作。

每次加入一个内置类型的数据成员时。不要忘记在每一个构造函数中对它进行初始化(採用int_data_(0)这种形式)。其实,这是一种easy出错的方法。假设忘了对这个数据成员进行初始化,它非常可能填充了垃圾信息,详细取决于计算机和应用程序曾经的历史。可能导致奇怪且非常难复制的行为。因此,为了防止这种错误。我们应该怎么做?

首先我们讨论下这个问题是与内置类型有关的。观察std::string类型的数据成员some_text_。

当我们向MyClass类加入数据成员some_text_时。并不须要在MyClass类的每一个构造函数中对它进行初始化,由于std::string的默认构造函数将会被编译器自己主动调用,把some_text_初始化为一个可反复的状态(此例中为空字符串)。

可是内置类型并没有构造函数,我们应该怎么办呢?事实上非常easy,对于类的数据成员。不要使用内置类型,而是使用类。例如以下:

  • 不要使用int,改用Int
  • 不要使用unsigned,改用Unsigned
  • 不要使用double。改用Double

以此类推。我们能够看例如以下代码,即模板类TNumber:

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_;
};

首先。接受T类型(T是不论什么内置类型,比如int、double、float等)的构造函数。并没有声明explicit。

这是有意而为之的。这个类所声明的下一个函数是operator T(),它同意把这个类的实例隐式转换回相应的内置类型。这个类有意设计为非常easy在它与内置类型之间方便地来回转换。它还定义了几个常见的操作符。它们也是使用内置的数值类型时所期望使用的。

下面是我们能够使用的实际类型的定义:

<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>

我们应该如何使用像Int和Double这种新类型呢?它们看上去与内置类型相似,仅仅是以大写字母开头。这些类型的使用方法与相应的内置类型全然同样。唯一的差别是它们都有一个默认构造函数把它们初始化为零。

这样,以MyClass类为例,我们能够採用下面的写法:

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_data_被声明为以大写字母开头的Int类型,而不是int。这样,我们就不须要在全部的构造函数中加入对它进行初始化的代码。它将自己主动被初始化为零。

实际上另一个差别:当我们使用内置类型时,试图将它除零可能导致不同的结果,详细取决于编译器和操作系统。为了保持一致。这个执行时错误将导致调用与处理其它错误同样的错误处理函数,使我们能够对错误进行调试。

健壮的代码不应该在变量被初始化之前引用它们。可是,假设确实发生了这种情况。让未初始化的变量具有一个像零这种安全值,显然要比具有随机的垃圾值好得多。

初始化的数值(int、double等)(一)的更多相关文章

  1. C# 判断字符串是否是int/double

    using System.Text.RegularExpressions; /// <summary> /// 判断字符串是否是int/double /// </summary> ...

  2. .build_release/lib/libcaffe.so: undefined reference to `cv::VideoCapture::set(int, double)'

    CXX/LD -o .build_release/tools/convert_imageset.bin.build_release/lib/libcaffe.so: undefined referen ...

  3. CodeForces - 93B(贪心+vector<pair<int,double> >+double 的精度操作

    题目链接:http://codeforces.com/problemset/problem/93/B B. End of Exams time limit per test 1 second memo ...

  4. string 与 int double 的转化

    #include <iostream> #include <string> #include <sstream> using namespace std; int ...

  5. arduino:int & double 转string 适合12864下使用

    转自:http://www.geek-workshop.com/forum.php?mod=viewthread&tid=3383&highlight=12864 很多人在玩的时候,都 ...

  6. 通过测试确定GCC中 INT DOUBLE的最大/最小值和精度(DOUBLE)

    INT 确定最大/最小值 由于达到极限之后会变符号,直接循环判断条件即可 DOUBLE确定精度 设置一个DOUBLE变量初始值为1/3.0,每次*10,然后取整数部分,当两次的结果相同时说明已经到最大 ...

  7. int,double与机器字长

    机器字长:计算机能直接处理的二进制数据的位数,它决定了计算机的运算精度想深入了解. 学好汇编语言对你帮助非常大.汇编语言中的,最基本的数据类型有: (1) byte (2)word (3)double ...

  8. 用C#.NET调用Java开发的WebService传递int,double问题

    用C#.NET调用Java开发的WebService时,先在客户端封装的带有int属性的对象,当将该对象传到服务器端时,服务器端可以得到string类型的属性值,却不能得到int类型.double和D ...

  9. int/double/string使用

    在计算机中存储数据和儿童在抽屉中存放物品很类似. 例如: 要在计算机中存一个数字50,需要两句话. int a;  //将要放的物品告诉家长 a=50;  //将物品放到某个抽屉中 计算机存储变量的过 ...

随机推荐

  1. 每天自己主动备份mysql脚本

    定时运行脚本: 1.运行 crontab -e 00 00 * * * /bin/bash yourpath/mysqlbak.sh 2.打开自己主动运行文件 vi /etc/crontab 在etc ...

  2. linux虚拟机网络设置好ping百度没有用

    场景:公司内网,本机使用的是本地连接,不是wiff,虚拟机设置了桥接模式 问题:使用桥接模式 启动好网络服务,查看ifconfig也获取到了设置的ip,可是ping了www.baidu.com还是没有 ...

  3. POJ3249 Test for Job(拓扑排序+dp)

    Test for Job Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10137   Accepted: 2348 Des ...

  4. DB-MySQL:MySQL 教程

    ylbtech-DB-MySQL:MySQL 教程 1.返回顶部 1. MySQL 教程 MySQL 是最流行的关系型数据库管理系统,在WEB应用方面 MySQL 是最好的RDBMS(Relation ...

  5. 关于volatile的一些思考C++

    在c++中,volatile用与修饰容易变动的变量,通常用于多线程的标志,编译器会存在代码优化,假如在同一个大括号中没有修改这么一个参数,那么编译器很可能在读取这个值的时候使用的是快取的方法,即将这个 ...

  6. javascript前端如何使用google-protobuf

    1.首先下载google的protobuf的compiler,通过编译器可以将.proto文件转换为想要的语言文件. 下载地址:https://repo1.maven.org/maven2/com/g ...

  7. MongoDB在MacOS上的客户端Robo 3T 的简单使用(二)

    最近写了一个用node来操作MongoDB完成增.删.改.查.排序.分页功能的示例,并且已经放在了服务器上地址:http://39.105.32.180:3333. 本篇文章只做简单介绍,能够使用起来 ...

  8. TextView 限制最大行数、最小行数、字数超过“...”表示

    最小行数: android:minLines = "2" //最小行数为2 最大行数: android:maxLines = "2" //最大行数为2 文字超过 ...

  9. tomcat 和 jboss的热部署(热发布)问题

    所谓的热部署(热发布)(下面称为“热部署”),就是说,在web工程发布之后,不可避免的,会遇到修改BUG的问题.现在的热部署就是为了解决这个问题,其功能就是说:在不停止web服务的同时,对jsp和Ja ...

  10. iOS UIImage的解码时机

    在看博客 UITableView优化技巧 时想到列表的优化主要还是对图片的优化处理. 博文中介绍了按需加载.快速滑动时不加载.异步刷新等等技巧. 这里有个问题, 当我们实例化一个UIImage对象并为 ...