如何cout<实际工作? [英] how does cout << actually work?

查看:137
本文介绍了如何cout<实际工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道 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&lt;实际工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆