如何cout<实际工作? [英] how does cout << actually work?
问题描述
我想知道 std :: cout
如何使用<<
/ p>
我的主要困惑是是否 std :: cout
作为一个实例。基本上,如何定义<<
?如果我这样做一个自定义类,我需要一个类的实例...
我可以看到它实现它作为一个黑客用void指针或东西,但我想看看它的实际做法。
这里有人知道吗?
感谢
std :: cout
std :: ostream
。 std :: cout<< c> > >
它是特殊的,因为它引用控制台,否则它的行为完全与 ofstream > code>或
ostringstream
。
EDIT 喜欢它适用于任何其他运营商。考虑:
class MyType
{
friend std :: ostream& operator<<(std :: ostream& target,const MyType& source);
int val;
public:
MyType()
:val(0)
{}
MyType& Add(int toAdd)
{
val + = toAdd;
return * this;
}
};
MyType& operator +(MyType& target,int toAdd)
{
return target.Add(toAdd);
}
std :: ostream& operator<<<(std :: ostream& target,const MyType& source)
{
target< source.val;
return target; // Make chaining work
}
int main()
{
MyType value1;
value1 + 2 + 3 + 4;
std :: cout<< value1<< 并做了! << std :: endl;
}
在这种情况下, MyType
工作的原因与<<
在 std :: ostream
。 +
和<<
都是左关联的,这意味着它们从左到右进行评估。在重载运算符的情况下,用等效函数调用替换运算符。
EDIT2 :更多细节:
假设您是编译器并且正在解析
std: :cout< value1<< 并做了! << std :: endl;
首先,剩下<<
关联,所以你从左边开始。您评估第一个<
operator<<(std :: cout,value1)<< 并做了! << std :: endl;
然后你会看到你再次有一个 std :: ostream
(调用
运算符<
的结果)和 char *
您再次转为函数调用:
运算符<<(运算符< ,and done!)<< std :: endl;
等等,直到您处理完整个语句。
I was wondering how std::cout
is able to use <<
as it does.
My main puzzlement is with whether std::cout
as an instance of something. Basically, how is <<
defined? If I do this for a custom class, I need an instance of some sort...
I could see implementing it as kind of a hack with void pointers or something, but I'd like to see the actual way it's done.
Does anyone here know? Thanks
std::cout
is an instance of std::ostream
. std::cout << "something"
calls one of the operator<<
overloads as would be done for any instance of std::ostream
.
It's "special" in that it references the console, but otherwise it behaves exactly as an ofstream
or an ostringstream
would.
EDIT: Chaining works just like it works for any other operators. Consider:
class MyType
{
friend std::ostream& operator<<(std::ostream& target, const MyType& source);
int val;
public:
MyType()
: val(0)
{ }
MyType& Add(int toAdd)
{
val += toAdd;
return *this;
}
};
MyType& operator+(MyType& target, int toAdd)
{
return target.Add(toAdd);
}
std::ostream& operator<<(std::ostream& target, const MyType& source)
{
target << source.val;
return target; //Make chaining work
}
int main()
{
MyType value1;
value1 + 2 + 3 + 4;
std::cout << value1 << " and done!" << std::endl;
}
In this case, the chaining for +s on MyType
work for the same reason the <<
s work on top of std::ostream
. Both +
and <<
are left-associative, which means they're evaluated from left to right. In the case of overloaded operators, the operator is replaced with the equivalent function call.
EDIT2: In a bit more detail:
Let's say you're the compiler and you're parsing
std::cout << value1 << " and done!" << std::endl;
First, <<
is left associative, so you start on the left. You evaluate the first <<
and turn it into the function call:
operator<<(std::cout, value1) << " and done!" << std::endl;
You then see that you once again have a std::ostream
(the result of the call to operator<<
), and a char *
, which you once again turn into the function call:
operator<<(operator<<(std::cout, value1)," and done!") << std::endl;
et cetera until you've processed the entire statement.
这篇关于如何cout<实际工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!