- 浏览: 2057193 次
- 性别:
- 来自: 北京
-
文章分类
- 全部博客 (795)
- java (263)
- 聚类搜索引擎 (9)
- 经验之谈 (67)
- DSP (3)
- C++ (140)
- Linux (37)
- SNMP (6)
- Python (6)
- 数据库 (61)
- 网络 (20)
- 算法 (15)
- 设计模式 (4)
- 笔试题 (38)
- 散文 (35)
- 数据结构 (9)
- 银行知识 (0)
- 榜样 (9)
- Lucene (15)
- Heritrix (6)
- MetaSeeker (0)
- netbeans (12)
- php (3)
- 英语 (8)
- DB2 (0)
- java基础 (5)
- mongodb & hadoop (4)
- Javascript (7)
- Spring (4)
- ibatis & myibatis (1)
- velocity (1)
- 微服务 (0)
- paddle (1)
- 第三方 (0)
- 知识沉淀 (1)
- 建模 (0)
最新评论
-
0372:
标示对java很陌生!
中文乱码解决的4种方式 -
梦留心痕:
Java中\是转意字符, 可是你的这句话我没看懂,只要把得到的 ...
java中如何忽略字符串中的转义字符--转载 -
yanjianpengit:
[b][/b]
java为什么非静态内部类里面不能有静态成员 -
springdata-jpa:
可以参考最新的文档:如何在eclipse jee中检出项目并转 ...
eclipse 如何把java项目转成web项目 -
qq1130127172:
,非常好。
(转)SpringMVC 基于注解的Controller @RequestMapping @RequestParam..
程序员间交谈时,经常把仅仅需要一小段时间的变量称为临时变量。例如在下面这段swap(交换)例程里:
template<class T>
void swap(T& object1, T& object2)
{
T temp = object1;
object1 = object2;
object2 = temp;
}
通常把temp叫做临时变量。不过就C++而言,temp根本不是临时变量,它只是一个函数的局部对象。
在C++中真正的临时对象是看不见的,它们不出现在我们的源代码中。建立一个没有命名的非堆(non-heap)对象会产生临时对象。这种未命名的对象通常在两种条件下产生:为了使函数成功调用而进行隐式类型转换和函数返回对象时。理解如何和为什么建立这些临时对象是很重要的,因为构造和释放它们的开销对于程序的性能来说有着不可忽视的影响。
首先考虑为使函数成功调用而建立临时对象这种情况。当传送给函数的对象类型与参数类型不匹配时会产生这种情况。例如一个函数,它用来计算一个字符在字符串中出现的次数:
// 返回ch在str中出现的次数
size_t countChar(const string& str, char ch);
char buffer[MAX_STRING_LEN];
char c;
// 读入到一个字符和字符串中,用setw避免缓存溢出,当读取一个字符串时
cin >> c >> setw(MAX_STRING_LEN) >> buffer;
cout << "There are " << countChar(buffer, c)
<< " occurrences of the character " << c
<< " in " << buffer << endl;
看一下countChar的调用。第一个被传送的参数是字符数组,但是对应函数的正被绑定的参数的类型是const string&。仅当消除类型不匹配后,才能成功进行这个调用,编译器很乐意替你消除它,方法是建立一个string类型的临时对象。通过以buffer做为参数调用string的构造函数来初始化这个临时对象。countChar的参数str被绑定在这个临时的string对象上。当countChar返回时,临时对象自动释放。
这样的类型转换很方便(尽管很危险),但是从效率的观点来看,临时string对象的构造和释放是不必要的开销。通常有两个方法可以消除它。一种是重新设计代码,不让发生这种类型转换。另一种方法是通过修改软件而不再需要类型转换。
仅当通过传值(by value)方式传递对象或传递常量引用(reference-to-const)参数时,才会发生这些类型转换。当传递一个非常量引用(reference-to-non-const)参数对象,就不会发生。考虑一下这个函数:
void uppercasify(string& str); // 把str中所有的字符
// 改变成大写
在字符计数的例子里,能够成功传递char数组到countChar中,但是在这里试图用char数组调用upeercasify函数,则不会成功:
char subtleBookPlug[] = "Effective C++";
uppercasify(subtleBookPlug); // 错误!
没有为使调用成功而建立临时对象,为什么呢?
假设建立一个临时对象,那么临时对象将被传递到upeercasify中,其会修改这个临时对象,把它的字符改成大写。但是对subtleBookPlug函数调用的真正参数没有任何影响;仅仅改变了临时从subtleBookPlug生成的string对象。无疑这不是程序员所希望的。程序员传递subtleBookPlug参数到uppercasify函数中,期望修改subtleBookPlug的值。当程序员期望修改非临时对象时,对非常量引用(references-to-non-const)进行的隐式类型转换却修改临时对象。这就是为什么C++语言禁止为非常量引用(reference-to-non-const)产生临时对象。这样非常量引用(reference-to-non-const)参数就不会遇到这种问题。
建立临时对象的第二种环境是函数返回对象时。例如operator+必须返回一个对象,以表示它的两个操作数的和。例如给定一个类型Number,这种类型的operator+被这样声明:
const Number operator+(const Number& lhs,const Number& rhs);
这个函数的返回值是临时的,因为它没有被命名;它只是函数的返回值。必须为每次调用operator+构造和释放这个对象而付出代价。
通常我们不想付出这样的开销。对于这种函数,可以切换到operator=,而避免开销。不过对于大多数返回对象的函数来说,无法切换到不同的函数,从而没有办法避免构造和释放返回值。至少在概念上没有办法避免它。然而概念和现实之间又一个黑暗地带,叫做优化,有时能以某种方法编写返回对象的函数,以允许编译器优化临时对象。这些优化中,最常见和最有效的是返回值优化。
综上所述,临时对象是有开销的,所以应该尽可能地去除它们,然而更重要的是训练自己寻找可能建立临时对象的地方。在任何时候只要见到常量引用(reference-to-const)参数,就存在建立临时对象而绑定在参数上的可能性。在任何时候只要见到函数返回对象,就会有一个临时对象被建立(以后被释放)。学会寻找这些对象构造,就能显著地增强透过编译器表面动作而看到其背后开销的能力。
template<class T>
void swap(T& object1, T& object2)
{
T temp = object1;
object1 = object2;
object2 = temp;
}
通常把temp叫做临时变量。不过就C++而言,temp根本不是临时变量,它只是一个函数的局部对象。
在C++中真正的临时对象是看不见的,它们不出现在我们的源代码中。建立一个没有命名的非堆(non-heap)对象会产生临时对象。这种未命名的对象通常在两种条件下产生:为了使函数成功调用而进行隐式类型转换和函数返回对象时。理解如何和为什么建立这些临时对象是很重要的,因为构造和释放它们的开销对于程序的性能来说有着不可忽视的影响。
首先考虑为使函数成功调用而建立临时对象这种情况。当传送给函数的对象类型与参数类型不匹配时会产生这种情况。例如一个函数,它用来计算一个字符在字符串中出现的次数:
// 返回ch在str中出现的次数
size_t countChar(const string& str, char ch);
char buffer[MAX_STRING_LEN];
char c;
// 读入到一个字符和字符串中,用setw避免缓存溢出,当读取一个字符串时
cin >> c >> setw(MAX_STRING_LEN) >> buffer;
cout << "There are " << countChar(buffer, c)
<< " occurrences of the character " << c
<< " in " << buffer << endl;
看一下countChar的调用。第一个被传送的参数是字符数组,但是对应函数的正被绑定的参数的类型是const string&。仅当消除类型不匹配后,才能成功进行这个调用,编译器很乐意替你消除它,方法是建立一个string类型的临时对象。通过以buffer做为参数调用string的构造函数来初始化这个临时对象。countChar的参数str被绑定在这个临时的string对象上。当countChar返回时,临时对象自动释放。
这样的类型转换很方便(尽管很危险),但是从效率的观点来看,临时string对象的构造和释放是不必要的开销。通常有两个方法可以消除它。一种是重新设计代码,不让发生这种类型转换。另一种方法是通过修改软件而不再需要类型转换。
仅当通过传值(by value)方式传递对象或传递常量引用(reference-to-const)参数时,才会发生这些类型转换。当传递一个非常量引用(reference-to-non-const)参数对象,就不会发生。考虑一下这个函数:
void uppercasify(string& str); // 把str中所有的字符
// 改变成大写
在字符计数的例子里,能够成功传递char数组到countChar中,但是在这里试图用char数组调用upeercasify函数,则不会成功:
char subtleBookPlug[] = "Effective C++";
uppercasify(subtleBookPlug); // 错误!
没有为使调用成功而建立临时对象,为什么呢?
假设建立一个临时对象,那么临时对象将被传递到upeercasify中,其会修改这个临时对象,把它的字符改成大写。但是对subtleBookPlug函数调用的真正参数没有任何影响;仅仅改变了临时从subtleBookPlug生成的string对象。无疑这不是程序员所希望的。程序员传递subtleBookPlug参数到uppercasify函数中,期望修改subtleBookPlug的值。当程序员期望修改非临时对象时,对非常量引用(references-to-non-const)进行的隐式类型转换却修改临时对象。这就是为什么C++语言禁止为非常量引用(reference-to-non-const)产生临时对象。这样非常量引用(reference-to-non-const)参数就不会遇到这种问题。
建立临时对象的第二种环境是函数返回对象时。例如operator+必须返回一个对象,以表示它的两个操作数的和。例如给定一个类型Number,这种类型的operator+被这样声明:
const Number operator+(const Number& lhs,const Number& rhs);
这个函数的返回值是临时的,因为它没有被命名;它只是函数的返回值。必须为每次调用operator+构造和释放这个对象而付出代价。
通常我们不想付出这样的开销。对于这种函数,可以切换到operator=,而避免开销。不过对于大多数返回对象的函数来说,无法切换到不同的函数,从而没有办法避免构造和释放返回值。至少在概念上没有办法避免它。然而概念和现实之间又一个黑暗地带,叫做优化,有时能以某种方法编写返回对象的函数,以允许编译器优化临时对象。这些优化中,最常见和最有效的是返回值优化。
综上所述,临时对象是有开销的,所以应该尽可能地去除它们,然而更重要的是训练自己寻找可能建立临时对象的地方。在任何时候只要见到常量引用(reference-to-const)参数,就存在建立临时对象而绑定在参数上的可能性。在任何时候只要见到函数返回对象,就会有一个临时对象被建立(以后被释放)。学会寻找这些对象构造,就能显著地增强透过编译器表面动作而看到其背后开销的能力。
发表评论
-
DLL中导出函数的声明有两种方式:
2012-11-12 16:42 1894DLL中导出函数的声明有两种方式: 一种方式是:在函数声明中 ... -
k-means算法的C++实现
2011-04-05 11:38 2358k-means算法的C++实现: http://www.ku ... -
main()中的参数
2010-10-31 10:41 1552所有的应用程序都是从以main函数作为入口, 而mai ... -
static作用
2010-10-26 19:15 2415转自(from http://www.cnb ... -
mmap函数
2010-10-25 22:41 1933mmap函数的使用方法 UNIX ... -
C语言中三种内存分配方式
2010-10-25 20:23 01.malloc 原型:extern void *ma ... -
位拷贝和值拷贝
2010-10-23 15:37 1616为了便于说明我们以String类为例: 首先定义String ... -
(转帖)把类的析构函数写成虚函数的用意
2010-10-23 15:10 1715#include <iostream.h> cl ... -
动态规划/贪心算法----0/1背包问题AND普通背包问题
2010-10-23 14:03 6842两个背包问题都是比较典型的问题,对这两种算法的理解有很好的帮助 ... -
netstat, nslookup, finger, ping命令
2010-10-22 17:13 1565Netstat用于显示与IP、TCP ... -
C++返回值
2010-10-22 16:53 1594C++函数返回值: (1)正常情况下,函数的参数要复制一份在 ... -
switch语句后的表达式的值
2010-10-22 16:23 1859一般格式: switch (表达式) { case 常量 ... -
C++四种强制类型转换
2010-10-19 11:45 1588显式类型转换又被称之 ... -
C++四种强制类型转化的区别
2010-10-19 11:43 1370先介绍const_cast和reinterpret_cast: ... -
Visual C++线程同步技术剖析:临界区,时间,信号量,互斥量
2010-10-18 14:24 1845使线程同步 在程序中使用多线程时,一般很少有多个线程能在其 ... -
(转)临界区,互斥量,信号量,事件的区别
2010-10-18 14:22 1786四种进程或线程同步互斥的控制方法1、临界区:通过对多线程的串行 ... -
(转)在C++中实现同步锁,类似synchronize(object){....}
2010-10-18 13:49 1899在做C++的项目中发现, ... -
C++线程同步
2010-10-18 13:46 1637线程同步是多 ... -
C++多线程编程
2010-10-18 10:56 1767今天我给大家讲一讲C++ ... -
关于C++对函数传参与函数返回值进行引用传递的详解
2010-10-16 22:51 4077关于C++对函数传参与函数返回值进行引用传递的详解 ...
相关推荐
c++中,临时对象一旦不需要,就会调用析构函数,释放其占有的资源;而具名对象则是与创建的顺序相反,依次调用析构函数。 c++源码: 代码如下:class X {public: int i; int j; ~X() {} X() {}}; int main() { X...
### C++中的临时对象 #### 一、引言 在C++编程中,临时对象是一个非常重要但又常常被忽视的概念。这些对象虽然不直接出现在源代码中,但在编译器生成的目标代码中却扮演着至关重要的角色。了解临时对象如何产生、...
常引用在保护函数参数不被修改时特别有用,同时也解决了C++中临时对象通常为const类型的问题,防止了非const引用尝试修改const对象的非法操作。 在实际编程中,理解并熟练运用引用,尤其是常引用,能够编写出更加...
在C++编程语言中,临时对象(Temporary Object)是指在表达式中为了完成特定操作而临时创建的对象。这些对象通常不被程序员直接命名,而是由编译器在幕后生成并管理。临时对象主要出现在以下几个场景: 1. **无名...
深入解析C++中的临时变量:理解其本质与作用 在C++编程中,临时变量扮演着至关重要的角色,尽管它们通常在代码中“隐身”,但它们的存在极大地影响着程序的性能和行为。本文将深入探讨C++中的临时变量,从操作系统...
《深度探索C++对象模型》专注于C++面向对象程序设计的底层机制,包括结构式语意、临时性对象的生成、封装、继承,以及虚拟——虚拟函数和虚拟继承。这本书让你知道:一旦你能够了解底层实现模型,你的程序代码将获得...
C++中的临时对象是指在表达式中为了完成特定任务而临时创建的对象,它们在程序运行过程中通常是不可见的,并且生命期很短。临时对象的创建可能会带来性能上的开销,尤其是在涉及拷贝构造函数或者多态性时。在本文中...
### C++中的临时变量 #### 一、引言 在C++编程中,临时变量是一个非常重要但又常常被忽视的概念。这些特殊的变量由编译器自动生成,用于处理某些特定情况下的数据操作,如函数调用时的参数传递或者作为函数返回值...
下面的例子中,`f(A())`返回一个引用,该引用绑定到一个临时对象,即使临时对象作用域结束,只要引用还在使用,临时对象就不会被销毁。 ```cpp const A& f(const A& a){ return a; } int main(){ { const A& a ...
在C++中,当一个对象作为参数按值传递时,会创建该对象的一个临时副本。这个过程可能导致性能上的开销,特别是在传递大型数据结构时,因为需要复制整个对象的内存空间。 例如: ```cpp void swap(int a, int b) { ...
本书探讨了大量的C++面向对象程序设计的底层运作机制,包括构造函数,函数,临时对象,继承,虚拟,模板的实例化,异常处理,运行期类型识别等,另外还介绍了一些在实现C++对象模型过程中做出的权衡折衷.喜欢刨根问底的C++...
- **临时对象的管理**:讨论临时对象的生命周期及其如何被正确处理。 #### 结语 通过以上内容,我们可以看出C++对象模型是一个庞大且复杂的主题。理解这些基础知识不仅可以帮助我们编写出更高效、更安全的代码,还...
这样做可以避免临时对象的创建和销毁,从而提高性能。例如: ```cpp class Base { public: Base(int val) : value(val) {} private: int value; }; class Derived : public Base { public: Derived(int baseVal...
Meyers在书中不仅介绍了如何避免不必要的对象构造和复制,还涉及到了如何合理利用临时对象、返回值优化等高级技术。例如,使用引用传递代替值传递可以减少不必要的对象构造,而当需要返回一个临时对象时,如果返回...
本书专注于C++面向对象程序设计的底层机制,包括结构式语意、临时性对象的生成、封装、继承,以及虚拟——虚拟函数和虚拟继承。这本书让你知道:一旦你能够了解底层实现模型,你的程序代码将获得多么大的效率。...
在C++编程中,临时量和临时对象是两个重要的概念,它们在程序执行过程中起着关键的作用。本文将深入探讨这两个概念以及相关的程序优化策略。 首先,临时量是指在表达式中生成的、用于临时存储结果的量。对于内置...