zoukankan      html  css  js  c++  java
  • 由作业题引发对C++引用的一些思考

    首先分析一段代码:

    #include <bits/c++config.h>
    #include <ostream>
    #include <iostream>
    #include <cstdio>
    using namespace std;
    class Node{
        int x;
        public:
        Node(int x=0):x(x){
        }
    
    };
    Node get(){
        return Node(5);
    }
    int main(){
        Node & i =  get();  
        return 0;
    }
    View Code

    一点编译,输出一行编译错误

    test1.cpp:25:21: error: invalid initialization of non-const reference of type ‘Node&’ from an rvalue of type ‘Node’

         Node & i =  get();

    意思是不能将Node类型的右值复制给Node&类型的变量。

    我尝试改一下源代码,主函数改为

    1 int main(){
    2   //int & n = 5;
    3 Node t = get(); 4 Node & i = t ; 5
    5   return 0; 6 }

    发现程序可以编译了。仔细对比这两段代码,我们可以得到这样一个事实:函数中返回的值相当于一个常量,它是临时产生的。只有当把这个函数的返回值赋值给变量的时候,我,们可以把变量的值赋值给Node&类型的变量。为了验证这个猜测,我们去掉上边的注释:

    test1.cpp:24:15: error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of

     type ‘int’

         int & t = 5;


    这个编译错误和上边的编译错误基本是一致的,从而验证了我们的猜测。

    在这个问题的基础上,我们研究这样一个问题

     1 #include <bits/stdc++.h>
     2 #include <istream>
     3 using namespace std;
     4 class Character{
     5     char c;
     6     public:
     7     Character(){}
     8     Character(char c):c(c){}
     9     Character  operator + (const int ch){
    10         return Character(((c+ch-'a')%26+26)%26+'a');
    11     }
    12     Character  operator - (const int ch){
    13         return  Character(((c-ch-'a')%26+26)%26+'a');
    14     }
    15     friend istream & operator >> (istream &is, Character &ch);
    16     friend ostream & operator << (ostream &os, Character &ch);
    17 };
    18 ostream &operator << (ostream &os, Character &ch){
    19     os << ch.c ;
    20     return os;
    21 }
    22 istream &operator >> (istream &is, Character& ch){
    23     is >> ch.c;
    24     return is;
    25 }
    26 int main()
    27 {
    28     int cases, data;
    29     Character ch;
    30     int d;
    31     cin>>cases;
    32     for (int i = 0; i < cases; i++)
    33     {
    34         cin>>ch;
    35         cin>>data;
    36         cout<<(ch + data)<<" "<<(ch - data)<<endl;
    37     }
    38 }

    编译上边的代码,我们得到一连串编译错误信息,看的头都大。不过不要过于担心。我们经常会因为一个小错误产生连锁反应才产生了如此多的错误。我们要做的是查找最本源的那个bug。

    首先我想到的可能<<的重载写的有问题,我查阅了iostream,ostream头文件的源码,确定了与之相关的函数

    1  inline basic_ostream<_CharT, _Traits>&  operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s);
    2  inline basic_ostream<_CharT, _Traits>&  operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c);

    我根据源码判断,<<重载的大致应该是这个函数,从刚才的一大串编译错误中似乎也能验证这一点,里面包含源码中的第2行语句。

    于是我根据源码第一行有const 这一事实,把<<的重载函数第二个参数前边都加上const,往第一条语句靠拢,程序成功编译了。或者我去掉引用,往第二条语句靠拢,程序同样编译成功了,更改代码如下。

    ostream &operator<<(ostream &os,Character a);
    ostream &operator<<(ostream &os,const Character &a);

    我们至此可以把程序改正确了。但还有一个问题没有解决,为什么仅仅去掉const就发生了编译错误了?

    这时结合我们一开始探讨的例子,这段代码和文章一开始的代码情况基本一致。即把一个返回非引用值的函数传给Character &。这下我们可以搞明白问题出现的原因了————函数的返回值作为隐式常量赋值给非 常引用致错。

    在此留几个还没搞明白的问题,提示:引用,类型转换,以备以后研究。

  • 相关阅读:
    视频上云解决方案EasyCVR支持接入海康SDK吗?
    视频上云网关EasyCVR程序数据库内数据会丢失吗?
    视频上云解决方案EasyCVR打包软件在linux下解压后台无法运行问题排查
    视频上云解决方案EasyCVR发布linux版本
    视频流媒体平台EasyNVR使用Vue.js开发报[Vue warn]错误问题解决方案
    监控现场无固定IP及公有云服务器如何通过手机查看视频直播?
    幼儿园EasyNVR能力层安防监控平台调用视频直播流报404错误解决方案
    海康NVR的RTSP视频流能否在EasyNVR流媒体平台中正常播放?
    视频云端流媒体平台EasyNVR存储的录像为什么呈现每小时一段录像?
    如何查看EasyNTS智能云组网硬件终端内的资源使用情况?
  • 原文地址:https://www.cnblogs.com/Wade-/p/6606637.html
Copyright © 2011-2022 走看看