前言
我学习C++的时候想要了解深入一点的知识,又由于我C++是零基础,同时C也和零基础差不多,但是个人学习风格习惯,喜欢深入学习,于是从C++ Primer plus 5的一个简单
std::cout << "Hello, World!" << std::endl;**
开始了深入理解。
AI阅读文章总结
这篇文章主要讲解了 C++ 中的输出流对象 std::cout 和相关的操作符重载。
首先,文章介绍了 std::cout 对象的原理,以及如何使用 << 插入运算符将字符串插入到输出流中。
其次,文章讲解了 std::endl 的作用,即在输出流中添加一个换行符,以及其源代码中使用的 C++ 模板语法。
接着,文章详细介绍了 << 运算符的重载概念和相关的源代码解释,以及 C++ 中如何使用模板来确定字符类型的特征集。
最后,文章通过自己实现一个输出功能,展示了如何使用命名空间和类来定制自己的输出流。
std::cout << "Hello, World!" << std::endl; 解析:
原理: 使用iostream库,同时导入也可以称之为iostream.h 的预处理 包含istream and ostream 两个基类,既输入/输出流
std::cout << "Hello, World!" << std::endl; 这个语句
是因为我们使用了(输出流)cout对象,他在iostream库中,被命名为extern ostream cout;并且设置为导出值
而<<运算符是插入运算符,能将值插入左边的对象,这个语句将"Hello, World!"字符串插入std::cout的输出流对象
而std::endl则是标识一个换行符,模板语法 return flush(__os.put(__os.widen('\n')));,这是源代码,同时他采用了C+的模板语法
template
inline basic_ostream<_CharT, _Traits>&
endl(basic_ostream<_CharT, _Traits>& __os)
{ return flush(__os.put(__os.widen('\n'))); }
扩展知识:
<<我们第一反应是左移操作符,在C++中他使用了重载概念,这是操作符重载,和Java的重载不同的是,他能函数和操作符重载
重载的<<源代码:
// Partial specializations
template
inline basic_ostream<char, _Traits>&
operator<<(basic_ostream<char, _Traits>& ___out, const char* __s)
{
if (!__s)
___out.setstate(ios_base::badbit);
else
__ostream_insert(___out, __s,
static_cast(_Traits::length(__s)));
return ___out;
}
其中operator<<是重载<<的运算符,同样可以operator+,则是重载+这个运算符
这里详细讲解一下<<重载和源代码的解释
**if (!__s)
___out.setstate(ios_base::badbit);**
这个语句告诉我们,判断传入的值是否为空,如果是空则返回baabit(标识流错误),倘若正确的就可以开始执行:
**else
__ostream_insert(___out, __s,
static_caststreamsize(_Traits::length()__s));
return ___out;**
这个语句告诉我们,如果不是空则会插入值,__s(指的是传入的const char的指针)
而后调用__ostream_insert,并调用静态成员static_cast,同时调用_Traits::length()__s),返回__s的字符串长度
同时使 static_cast
而Traits类型是用于在编译时确定char类型的特征集(traits)的类型参数
其中 template关键字是模板,typename定义一个类型名
inline则是在函数调用时,将这个函数代码插入函数调用的位置,避免函数调用的开销
而inline basic_ostreamchar,&则是标识运算符返回ostream的返回类型,同时basic_ostreamchar,&又是一个泛型,他用于输出char类型的输出流
自己实现一个输出功能
// 我们尝试简单魔改一下<<运算符,调用它的字符串会自动加上StarYuhen is: ,如果没有声明命名空间会告诉你编译器不知道调用哪个,我们可以写个命名空间
namespace YuhenStream {
// template<typename T>
// std::ostream &operator<<(std::ostream output, const T &value) {
// output << 'is StarYuhen' << value;
// return output;
// }
// class YuhenStreamBuf : public std::streambuf 这一句话申明YuhenStreamBuf继承std::streambuf,相当于Java的extends
class YuhenStreamBuf : public std::streambuf {
// public标识共有
public:
YuhenStreamBuf() {
setp(buffer, buffer + bufferSize - 1);
}
// 保护
protected:
virtual int_type overflow(int_type ch = traits_type::eof()) {
if (ch != traits_type::eof()) {
*pptr() = ch;
pbump(1);
}
return flushBuffer();
}
// 虚函数
virtual int sync() {
return flushBuffer();
}
// 私有
private:
int flushBuffer() {
if (pbase() == pptr()) {
return 0;
}
*pptr() = '\0';
std::cout << "StarYuhen is:" << buffer;
setp(buffer, buffer + bufferSize - 1);
return 0;
}
// 静态常量
static const int bufferSize = 64;
char buffer[bufferSize];
};
// 模板函数
template<typename T>
YuhenStreamBuf &operator<<(YuhenStreamBuf &out, const T &value) {
std::ostringstream ss;
ss << value;
std::string strValue = ss.str();
out.sputn(strValue.c_str(), strValue.size());
return out;
}
// 定义两个类型对象
YuhenStreamBuf yuhenStreamBuf;
std::ostream yuhenStream(&yuhenStreamBuf);
}