3

When we use printf then we use format specifiers (such as %c,%p) but when we use cout we don't use them why and what is being done in background because which we are not using them ?

I know they are used in differently in c and c++ but still i want to know how formatting is being done in cout, while it is done in printf through format specifiers.

4

3 回答 3

4

在 C++ 中,ostream::operator<<为不同的类型重载了。您可以尝试深入了解您的标准库实现以查看它的确切外观,但它会归结为大致相当于以下内容:

class ostream
{
public:
   ostream& operator<<( int val );
   ostream& operator<<( float val );
   ostream& operator<<( const char* val );
};

真正的实现会比上面的要复杂得多,但大致就是这样。希望这个实现比 printf 更有效,因为编译器可以在适当的时候更容易地内联代码。考虑以下:

int val = 0;
printf("%d\n", val);
std::cout << val << std::endl;

在 printf 的情况下,一个天真的编译程序(由不知道格式说明符的编译器编译的程序)必须在运行时解析“%d\n”。将其与 std::cout 调用进行对比,在这种情况下,编译器只需要确定要使用的重载,然后就可以内联代码。

也就是说,c 标准中没有任何内容表明编译器无法在编译时解析格式说明符(如果它们可用)。在实践中,使用格式说明符的 ac 样式日志库和 c++ ostreams 之间的性能差异是...细微差别的。

于 2013-09-24T04:49:36.223 回答
4

因为printf设计得当,cout内部状态很糟糕。使用printf,您希望每个参数格式化的方式在格式字符串中是明确的;没有隐藏状态。使用cout,您还可以控制格式(例如字段宽度等),但它是 iostream 对象内部的隐藏状态。如果流的前一个用户将其置于非默认状态,除非您明确重置状态,否则您将做错事。您甚至不想考虑在多线程用例中会发生什么......

于 2013-09-24T04:50:29.980 回答
0

基本上答案是运算符重载。函数可以具有相同的名称,只要它们采用不同的参数即可。operator<<是您想知道的函数名称。编译器知道您要打印的类型,并调用正确的operator<<.

这就是为什么如果您创建自己的对象,您不能只是编写std::cout << yourObject;并期望它按照您可能希望的方式工作。您必须指定应如何打印,

ostream& operator<<(ostream& os, const YourObject& rhs) {
  os << rhs.member;
  return os;
}

但是,令人高兴的是,对于像int. 有关提供的重载的完整列表,请参见:http ://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt2。

于 2013-09-24T04:45:40.473 回答