C++ 具有整数成员的对象的Printf

C++ 具有整数成员的对象的Printf,c++,printf,C++,Printf,我有这些奇怪的行为。 如果我使用下面的代码 class Simple { public: Simple() { m = 1; mm = 2; mmm = 3; } ~Simple() { } private: int mmm; int mm; int m; }; int main(int argc, char** argv) { Simple sim;

我有这些奇怪的行为。 如果我使用下面的代码

class Simple
{
public:
    Simple()
    {
        m = 1;
        mm = 2;
        mmm = 3;
    }

    ~Simple()
    {
    }

private:
    int mmm;
    int mm;
    int m;
};

int main(int argc, char** argv)
{
    Simple sim;

    printf("%d\n", sim);
}
作为打印结果,我得到了数字“3”。 如果我把声明放在第一位,例如变量“mm”而不是“mmm”,那么printf的结果就是数字“2”。 同样的行为,如果我把声明作为变量“m”放在第一位,printf给我“1”。
似乎printf可以打印声明的第一个int变量。怎么可能?

printf
是一个可变函数,这意味着它不知道如何检查第二个和后面参数的类型。因此,在典型的实现中,它相信您为它提供了正确类型的参数,如
%d
所示,即
int
。内存中的
sim
对象是三个
int
组合在一起的
printf
,给定
%d
,尝试读取
int
,并获取您在
sim
中声明的第一个
int
变量


请注意,这是未定义的行为,您不应该依赖它。

正如老话所说,未定义的行为是未定义的。请记住,当人们编写“未定义的行为”时,这意味着编程语言对于您正在学习的表达式没有标准行为。这意味着每个编译器供应商都可以决定如何处理它。@nicomp编译器不必决定如何处理它。他们可以简单地假设UB永远不会发生,因为他们不必关心UB发生时会发生什么。任何事情都有可能发生在未定义的行为中,所以你必须习惯它。C++和C的设计是高效的,所以在很多情况下,假设你知道你在做什么,并且没有错误检查为你构建。当您导致未定义的行为时,您不一定会出错,并且您的程序可能看起来工作正常。下次,请使用
std::cout
,从而学习如何正确实现
运算符这是有意义的。如果我写printf(“%d%d%d\n”,sim);,我有“321”。@VFG•只是更多未定义的行为,可能因编译器而异,或者取决于启用了哪些编译器优化。@VFG无论如何,这不是保证,只定义operator@VFG不,您现在编写的代码不能保证做任何明确的事情。如果您在不同的编译器上尝试或使用不同的编译器选项,甚至可能导致程序崩溃。@JoshWilson“printf是一个可变函数,这意味着它不知道如何检查第二个和后面参数的类型”-许多现代编译器在编译时为printf样式的函数提供参数验证,以确保在使用编译时字符串文字时,根据格式字符串传入有效参数。