`
harry
  • 浏览: 180122 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

内存与C++

阅读更多

不管什么时候运行一个程序,都是首先把它装入(一般从磁盘装入)计算机内存。因此程序中的所有元素都驻留在内存的某处。内存一般被布置成一系列连续的内存位置;我们通常把这些位置看做是8位的字节,但实际上每一个空间的大小取决于具体机器的结构,一般称为机器的字长(word size)。每一个空间可按它的地址与其他空间区分。


静态与动态内存分配的两个主要区别是:

1.静态对象是有名字的变量,我们直接对其进行操作。而动态对象是没有名字的变量,我们通过指针间接地对它进行操作。

2.静态对象的分配与释放由编译器自动处理。程序员需要理解这一点,但不需要做任何事情。相反,动态对象的分配与释放,必须由程序员显式地管理。相对来说比较容易出错,它通过new和delete两个表达式来完成。


“类的公共接口与私有实现的分离“被称为信息隐藏(information hiding)。

简单说来,它为程序提供了两个主要好处:

1.如果类的私有实现需要修改或扩展,那么只有相对很小一部分”要求访问这些实现的成员函数“才需要修改。许多使用该类的用户程序一般无需修改,但是要求重新编译。

2.如果类的私有实现有错误,那么通常需检查的代码数量只局限在相对较少的需要访问这些实现的成员函数上,而无需检查整个程序。


返回值优化

通过传值方式返回要创建新对象时,应注意使用的形式。

return Integer(left.i + right.i);

咋看起来这像是一个”对一个构造函数的调用“,其实并非如此。这是临时对象语法,它只在说:“创建一个临时Integer对象并返回它”。据此我们可能认为如果创建一个有名字的局部对象并返回它结果将会是一样的。其实不然。如果如下编写:

Integer tmp(left.i + right.i);

return tmp;

将发生三件事。首先,创建tmp对象,其中包括构造函数的调用,然后,烤贝构造函数把tmp烤贝到外部返回值的存储单元里。最后,当tmp在作用域的结尾时调用析构函数。

相反,“返回临时对象”的方式是完全不同的。当编译器看到我们这样做时,它明白对创建的对象没有其他需求,只是返回它,所以编译器直接地把这个对象创建在外部返回值内存单元。因为不是真正创建一个局部对象,所以仅需要一个不同构造函数调用(不需要拷贝构造函数),且不会调用析构函数。这种方法不需要什么花费,因此效率是非常高的,但程序员要理解这些。这种方式常被称作返回值优化(return value optimization)。


不能重载的运算符

在可用的运算符集合里存在一些不能重载的运算符。这样限制的通常原因是出于对安全的考虑:如果这些运算符也可以被重载,将会造成危害或破坏安全机制,使得事情变得更苦难或混淆现有的习惯。

1.成员选择operator.。点在类中对任何成员都有一定的意义。但如果允许它重载,就不能用普通的方法访问成员,只能用指针和指针operator->访问。

2.成员指针间接引用operator.*,因为与operator.同样的原因而不能重载。

3.没有求幂运算符。通常的选择是来自Fotran语言的operator**,但这出现了难以分析的问题。C没有求幂运算符,c++似乎也不需要,因为这可以通过函数调用来实现。求幂运算符增加了使用的方便,但没有增加新的语言功能,反而为编译器增加了复杂性。

4.不存在用户定义的运算符,即不能编写目前运算符集合中没有的运算符。不能这样做的部分原因是难以决定其优先级,另一部分原因是没有必要增加麻烦。

5.不能改变优先级规则,否则人们很难记住它们。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics