invalid initialization of non-const reference of type与discards qualifiers
函数参数的传递是初始化语义:用调用者的实参去初始化函数的形参,如果参数是对象,需要调用该类的拷贝构造函数,如果没有显式定义的拷贝构造函数,则执行默认的按成员拷贝
返回值传递
函数返回值的传递内容稍多,示例代码:
- TestClass get_test_obj()
- {
- TestClass ret_obj(200);
- return ret_obj;
- }
- void user()
- {
- TestClass obj:
- obj = get_test_obj();
- }
返回过程执行下列步骤:
1、get_test_obj() 中,用返回对象 ret_obj 初始化一个类型为 TestClass(返回类型)的 临时对象
tmp_obj(假设名),这个临时对象放置在调用者 user() 的栈内。GCC 4 和 VC 2005 使用返回值临时对象的方式不同,见下面
Bjarne
关于临时对象销毁的说法:临时对象在维持它的那条语句之后被销毁,除非临时对象被约束到其它名字,此时由这个命名名字控制临时对象的生存期。可以用对象初
始化的语法(显示或隐式的),或对象引用来约束这个临时对象,两者的效果是一样的,因为期间只有一个对象本体,就是临时对象的本体,约束期间不产生任何初
始化、赋值语义
2、get_test_obj() 中,由 ret_obj 的生存期,决定何时将其销毁。如果 ret_obj 是局部对象(形参 或 函数内定义非 static 变量),则在返回时销毁
3、如果
user() 中使用函数返回值进行 赋值操作 obj = get_test_obj(),则执行
obj.operator=(tmp_obj),没有重载的 TestClass::operator=(right) 和
::operator=(TestClass, right) 时,执行 TestClass 的每个成员的 operator=()
4、如果 user() 中使用函数返回值进行 初始化操作,包括以下几种语法:
TestClass obj = get_test_obj(); // 隐式初始化
TestClass obj(get_test_obj()); // 显式初始化
TestClass& obj_ref = get_test_obj(); // 初始化为引用,tmp_obj 被约束到引用名
隐式和显式初始化可能有 2 种实现:
(1)直接将函数 get_test_obj() 返回的临时对象 tmp_obj 约束到 obj,不调用 TestClass
的任何构造函数(包括拷贝构造函数),在初始化语句执行后,不会销毁 tmp_obj,而由 obj 控制 tmp_obj 的生存期
(2)调用 TestClass 的拷贝构造函数,以返回的 tmp_obj 为参数拷贝构造对象 obj.这种方式,在初始化语句执行后,tmp_obj 就没有用了,将被销毁
VC 2005 采用 (1) 方式实现
GCC 4 的返回值临时对象
-O0 关闭编译优化
无论是在
user() 内使用返回值赋值、初始化,还是不使用返回值,在 get_test_obj() 返回时,都 不创建额外的临时对象
tmp_obj,而直接将 get_test_obj() 的局部对象 TestClass ret_obj(200)
作为临时对象,即被调函数返回后,将其栈交给调用者控制,作为调用者的栈,这种返回对象的方法比 VC 2005 的效率高
下面是 GCC 4 中,调用者使用函数返回值的几种情况:
1、如果调用者没有使用返回值,在被调函数返回时销毁 return ret_obj 中的 ret_obj
2、进行返回值赋值 或 初始化对象时,方式和 VC 2005 类似,只是不创建临时对象 tmp_obj,而使用局部对象 ret_obj
3、当初始化返回值到引用名时,不能初始化到 非常量 的引用 TestClass& obj_ref = get_test_obj(),会报编译错误:
error: invalid initialization of non-const reference of type 'TestClass&'
from a temporary of type 'TestClass'
应该使用常量引用 const TestClass& obj_ref = get_test_obj()
另一个
GCC 4 有别于 VC 2005 的 const 保护行为:一个 const 对象调用的方法必需是 const 方法,比如 const
TestClass obj 调用 obj.print_intval() 时,如果不是 void print_intval()
const,会报编译错误:
error: passing 'const TestClass' as 'this' argument of
'void TestClass::print_intval()‘ discards qualifiers
invalid initialization of non-const reference of type与discards qualifiers的更多相关文章
- passing ‘const ’ as ‘this’ argument of ‘’ discards qualifiers 错误处理
示例程序: #include <iostream> #include <set> using namespace std ; class StudentT { publ ...
- 1月21日 Reference Data Type 数据类型,算法基础说明,二分搜索算法。(课程内容)
Reference Datat Types 引用参考数据类型 -> 组合数据类型 Array, Hash和程序员自定义的复合资料类型 组合数据的修改: 组合数据类型的变量,不是直接存值,而是存一 ...
- J2EE Exception:WELD-001408 Unsatisfied dependencies for type [SelectModelFactory] with qualifiers [@
Issue: When you inject some resources using @Inject, you may encounter following exception after app ...
- C++ error: passing 'const std::map<>]' discards qualifiers或pass-by-reference-to-const-map导致的“discards qualifiers”
产生问题的场景: int func(const map<int, string> &aMap) { string value = amap[0]; } 或者 int Test:: ...
- [C++]invalid initialization of non-const reference of type 'std::__cxx11::string& {aka std::__cxx11::basi
解决方法:在参数前面加一个cosnt或者把引用符号去掉
- variadic templates & pass by const reference & member operator [] in const map & gcc sucks
/// bugs code with comments #include <iostream> #include <memory> #include <unordered ...
- all index range ref eq_ref const system 索引type说明
背景知识 在使用sql的过程中经常需要建立索引,而每种索引是怎么处罚的又是怎么起到作用的,首先必须知道索引和索引的类型. 索引类型type 我们可以清楚的看到type那一栏有index ALL eq_ ...
- error: cannot bind non-const lvalue reference of type
这种问题一般是因为引用了匿名变量.涉及左值和右值的区别.一般函数的参数如果是一个表达式,那将会产生一个第3方的匿名变量传入这个函数中,此时如果引用,没用什么实际意义. c++中临时变量不能作为非con ...
- Passing Reference Data Type Arguments
public void moveCircle(Circle circle, int deltaX, int deltaY) { // code to move origin of circle to ...
随机推荐
- Tomcat日志问题
[Tomcat日志设定][tomcat控制台日志][log4j日志] 1 Tomcat 日志概述 Tomcat 日志信息分 为 两 类 : 一是运行中的日志,它主要 记录 运行的一些信息,尤其是一些异 ...
- Python十分钟学会
初试牛刀 假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(Cheat ...
- MAC终端配色Solarized
MAC终端配色Solarized $ git clone git://github.com/altercation/solarized.git 在 solarized/osx-terminal.app ...
- android sqlite 怎么写入存储时间
字符串类型2013-12-10 12:12:12 SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd"); ...
- UITableView的使用及性能优化
UITableView可谓是日常开发中最重要的控件之一,而使用UITableView最重要的在于性能优化.iOS设备的内存有限,如果用UITableView显示成千上万条数据,就需要成千上万个UITa ...
- 2、Spring的LocalSessionFactoryBean创建过程源码分析
spring的LocalSessionFactoryBean生成过程与hibernate的SessionFactory生成过程是高度吻合的. 为了后面源码分析,首先讲解一个接口,一个类的功能:①.接口 ...
- 【原创】通俗易懂地解决中文乱码问题(2) --- 分析解决Mysql插入移动端表情符报错 ‘incorrect string value: '\xF0...
这篇blog重点在解决问题,如果你对字符编码并不是特别了解,建议先看看 < [原创]通俗易懂地解决中文乱码问题(1) --- 跨平台乱码 >. 当然,如果只是针对解决这个Mysql插入报错 ...
- 基于矩阵模式的 Web 软件测试手段(转)
http://www.ibm.com/developerworks/cn/web/1410_dujing_matrixfortest/ 在 Web 测试中,我们经常针对某个测试点进行多种场景测试,或者 ...
- cmake的使用二:链接第三方静态库
cmake的使用二:链接第三方静态库
- YTU 2601: 熟悉题型——填空题(删除线性表节点)
2601: 熟悉题型--填空题(删除线性表节点) 时间限制: 1 Sec 内存限制: 128 MB 提交: 357 解决: 212 题目描述 给出一串具体长度的数据,删除指定数据. 已经给出部分代 ...