C++ 引用问题

Wesley13
• 阅读 622
  • 一个const的对象,调用自身用该都是const式的成员函数,因为非const成员函数可能会更改该对象,与const对象冲突。当然可以加上一个-fpermissive参数来稍微放松,但最好不要这样做。

  • 右值作为一个非const引用参数,编译器不允许。

  • 左值:可以取到地址并且有空间,内容可以改变的。

  • 右值:1.不可取地址,如常量1,2,3等。2.可以取地址但是该空间不可更改,如const 值,构造函数。3.本身就是常量值,如int test[4],test本身就是一个地址常量值,内部就是一个test指针变量,但该变量为const类型,可以归结到第二点。

注:该规则仅仅是对于**引用 &**来说。
类Lit
        const Lit a = Lit();
        Lit b = a;    //ok,仅仅是值的复制而已
        Lit &b = a;    //error,因为b改变了,a就改变,但a是const的,冲突。
像这种情况:
void fun(Lit & l){...}
int main()
{
    1.fun( Lit() );    //error,因为Lit()构造函数返回为右值

   2. Lit temp = Lit();
       fun( temp ) //ok,因为temp是一个左值
}
解除这种限制就是void fun( const Lit & l)
可以接受任何形式的Lit。
如果要返回Lit 如 
const Lit & fun(const Lit & l){ return l; }        //ok
Lit & fun( const Lit & l) { return l; }             //error
Lit fun(const Lit & l) { return l; } //ok此时会创建临时区域,仅仅是普通相对费时复制而已。

一种伪装式的临时变量
class Lit
{
    string s;
    public:
        Lit(string _s) : s(_s) {}
        ...;
        string getString() { return s; }
};
    const Lit & Mid( const Lit & l )
    {
        return l;
    }
   const Lit & returnLit()
    { return  Mid( Lit("hello") ); }
此函数若写成这样
const Lit & returnLit()
{ Lit a("hello"); return Mid(a); }两者运行都会报错
若是在Lit a("hello"); 加上static 那么就不会报错。即该对象会一直存在。
int main()
{
    const Lit & test = returnLit();
    string s = test.getString();
    cout<<s<<endl;
    return 1;
}
这种伪装式的变成风格编译器不会报错也不会警告,但是运行起来就会报段错误,这说明了不要去返回临时变量的引用。但在现实情况使用构造函数去给某个函数初始化的比比皆是,而以返回类引用函数形式的编程也比比皆是,就Mid函数来说,本身是完全正确的,而且是值得推荐的。对于某些GUI编程,设置一些东西常常使用构造函数,其实这些函数一般不会返回什么东西,他仅仅是作为设置来用。所以也没多大事。怎么说呢,当规模很大的时候,可能不经意或者设计的疏忽,会发生这种大问题。我觉得使用也要像使用指针那样小心为是,其实BJ也说就把它当做为const式的指针来考虑。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
这些JS工具函数够你用到2020年底了
前言活不多说,自己平时搜集的干货函数奉上。干货函数找出数字在数组中下一个相邻的元素let i  "";let rr  ;const name  (n, arr1)    let num  Number(n);    for (let i  0; i < arr1.length; i)         const elemen
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
go语言学习
iotaiota,特殊常量,可以认为是一个可以被编译器修改的常量。iota在const关键字出现时将被重置为0(const内部的第一行之前),const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。iota可以被用作枚举值:const(a
Stella981 Stella981
3年前
JS 对象数组Array 根据对象object key的值排序sort,很风骚哦
有个js对象数组varary\{id:1,name:"b"},{id:2,name:"b"}\需求是根据name或者id的值来排序,这里有个风骚的函数函数定义:function keysrt(key,desc) {  return function(a,b){    return desc ? ~~(ak
Wesley13 Wesley13
3年前
ES6 简单整理
1.变量声明let和constlet与const都是块级作用域,letfunctionname(){letage12;//age只在name()函数中存在}constconstname'tom'name'jack'//
Stella981 Stella981
3年前
Nginx反向代理upstream模块介绍
!(https://oscimg.oschina.net/oscnet/1e67c46e359a4d6c8f36b590a372961f.gif)!(https://oscimg.oschina.net/oscnet/819eda5e7de54c23b54b04cfc00d3206.jpg)1.Nginx反
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这