istream对象源码剖析

1 篇文章 0 订阅

istream对象——源码剖析

省流:istream对象只能接收左值,不能接收右值

1 先看看cin的使用

我们知道,cin可以接收一个对象,然后存入到对应的变量里面
例如

int a;
cin >> a;
cout << a;

如果我们输入的是10,那就会输出10(狗头:这不是废话嘛)

2 思考:能不能直接给cin一个字面值?

cin >> 10;输入一个10?答案是不能的。

示例代码
int main(int argc, char** argv)
{
	/* 	下面这条语句将会产生非常多的报错:
		error: no match for ‘operator>>’ (operand types are ‘std::istream’ {aka ‘std::basic_istream<char>’} and ‘int’)
		error: invalid conversion from ‘int’ to ‘std::basic_istream<char>::__istream_type& (*)(std::basic_istream<char>::__istream_type&)’ {aka ‘std::basic_istream<char>& (*)(std::basic_istream<char>&)’} [-fpermissive] 
		error: invalid conversion from ‘int’ to ‘std::basic_istream<char>::__ios_type& (*)(std::basic_istream<char>::__ios_type&)’ {aka ‘std::basic_ios<char>& (*)(std::basic_ios<char>&)’} [-fpermissive]
	 	error: invalid conversion from ‘int’ to ‘std::ios_base& (*)(std::ios_base&)’ [-fpermissive]
	 	error: cannot bind non-const lvalue reference of type ‘bool&’ to an rvalue of type ‘bool’
	 	...还有很多
	 */
	cin >> 10;//error

	
	return 0;
}

那为什么会报错呢?
我们先从第一条报错开始看(notify:一般来说遇到很多报错的时候,都是从最开始的那个报错开始看)

error: no match foroperator>>(operand types are ‘std::istream’ {aka ‘std::basic_istream<char>} andint)

上面这条报错的含义:

没有匹配' operator>> '(操作数类型为' std::istream '{也称为' std::basic_istream<char> '}' int ')

楼主英文比较蹩脚,就直接有道翻译了。乍一看有点难搞懂是啥意思,我再翻译一下(也不知道对不对,不对的话麻烦您告诉我怎么理解。谢谢)

没有找到匹配的 操作对象是std::istream(也称为std::basic_istream<char>)和int 的 重载>>操作符的函数

嘻嘻,有点眉目了,它说没有重载>>的函数与我们传入的参数匹配,那我们就去看看cin重载了哪些>>函数。

查看了cin的源码,cin是一个istream对象,而istream是一个别名而已,真正的类型是一个basic_istream模板类。

extern istream cin;
typedef basic_istream<char, char_traits<char>> istream;

而这个basic_istream模板类重载了>>,所有重载函数如下:

basic_istream::operator>>
重载的函数
basic_istream& operator>>(basic_istream& (* Pfn)(basic_istream&));
basic_istr eam& operator>>(ios_base& (* Pfn)(ios_base&));
basic_istream& operator>>(basic_ios<Char_T, Tr>& (* Pfn)(basic_ios<Char_T, Tr>&));
basic_istream& operator>>(basic_streambuf<Char_T, Tr>* strbuf);
basic_istream& operator>>(bool& val);
basic_istream& operator>>(short& val);
basic_istream& operator>>(unsigned short& val);
basic_istream& operator>>(int& val);
basic_istream& operator>>(unsigned int& val);
basic_istream& operator>>(long& val);
basic_istream& operator>>(unsigned long& val);
basic_istream& operator>>(long long& val);
basic_istream& operator>>(unsigned long long& val);
basic_istream& operator>>(void *& val);
basic_istream& operator>>(float& val);
basic_istream& operator>>(double& val);
basic_istream& operator>>(long double& val);

得出结论:由以上源码可知,istream对象只能接收左值(引用作为形参的函数,实参只能是左值,因为右值无法取其引用)

为了验证上述结论:再举个例子
目标:将Person的数据读入到isatream对象里面

#include<iostream>

using std::cin;
using std::cout;
using std::istream;
using std::string;

/*class Person start*/
class Person {
public:
    Person() {
        cout << "Person, The default constructor is called " << endl;
    }
    Person(string name, string addr, unsigned age)
    :m_strName(name), m_strAddress(addr), m_unAge(age) {
        cout << "Person, The constructor is called " << endl;
    }
    ~Person() {
        cout << "~Person, The desstructor is called " << endl;
    }

    void setName(string name) {
        m_strName = name;
    }
    void setAddress(string addr) {
        m_strAddress = addr;
    }
    void setAge(unsigned age) {
        m_unAge = age;
    }
    string getName() const {
        return m_strName;
    }
    string getAddress() const  {
        return m_strAddress;
    }
    unsigned getAge() const {
        return m_unAge;
    }
private:
    string m_strName;
    string m_strAddress;
    unsigned m_unAge{0};

};/*class Person end*/

istream& readPerson(istream& is, Person& p)
{
	//is >> p.getName() >> p.getAddress() >> p.getAge();//error
	string name = p.getName();
	string addr = p.getAddress();
	unsigned age = p.getAge();
	is >> name  >> addr >> age;
	return is;
}

注意了:

is >> p.getName() >> p.getAddress() >> p.getAge();//error

这个代码会报错,错误与上面的报错类似,有兴趣的朋友可自行验证一下。

3 结束语

到此,我们总算知道了为什么>>不能传入右值了。
如果文章对您有帮助,劳烦一键三连加关注哦。
初来乍到,如果文章内容有错误的地方或者有关于文章排版的建议、意见,麻烦留言指出。十分感谢

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值