1

假设我有一堂课:

class foo
{
    ....
    //some constructors here set val=34
    ....
    private:
    int val;
    int & foo::operator,()
    {
      return val;
    }
};

我希望能够将其用作:

foo bar;
printf("  %d ", bar);   //i need to get value of bar.val
                        //with just using bar itself with
                        //using an overloading
                        //but , overloading does not work
                        //i need to get 34 without using bar.val
                        //i need this without any getter 
                        //i need val to be private

问题:这种超载可能吗?如果是,如何?

我试过:

int foo::operator int()
{
    return val;
}

但它说“可能未在转换函数上指定返回类型”:(

我试过:

operator int() const { return val; } 

转换仅在 printf 和 cout 之外有效。

 int e=foo;
 printf(" %d ",e); //works 
4

3 回答 3

4

您不能重载一个类,但您可以使用转换运算符,以便它根据该上下文中的预期参数自动转换为不同的类型。在您的情况下,就像 一样valint您会将转换重载为int

operator int() const { return val; }

现在int,只要需要 a 并且您提供 a foo,就会应用此转换。

有一些限制。例如,如果您传递foo给相应参数的类型为泛型的函数模板,则该位置将不会进行转换。转换也不会影响不强制类型的其他表达式。例如,如果f是 type foo,那么&f将始终是 type foo*,而不是int*。对于大多数实际应用,这一切正是您所需要的。但我相信 C 风格的可变参数printf正是没有明确定义的预期类型的​​情况。最好使用 C++ 风格的调用或显式强制转换static_cast<int>(f)

如果两者都不适合您,那么您就有麻烦了:C++ 逻辑无法推断出您在int此处需要 a 的事实,仅仅因为您%d在某些字符串常量中包含了 a 。类型转换是编译时的事情,而格式字符串的解释是在运行时完成的(除了像 gcc 那样生成警告时)。编译器不知道该参数需要是什么类型,因此它不知道要执行什么转换,因此您必须以某种方式帮助他。

只要这int val是 的唯一成员foo,并且该类中也没有虚函数,并且没有具有任何数据成员的基类或虚函数,则类对象的内存布局foo通常是相同的作为一个普通整数。这意味着无类型的 C 风格printf将无法区分,即使根本没有任何转换。但是依靠这个真的很糟糕,所以我建议不要使用它。

于 2012-09-08T21:38:14.383 回答
2

不要超载逗号或其他可怕的东西。printf具有省略号参数,因此它接受您提供给它的任何内容,您必须确保您提供的内容是正确的。把事情简单化:

class foo
{
    ....
    //some constructors here set val=34
    ....
private:
    int val;
public:
    int value()
    {
      return val;
    }
};

int main()
{
    foo bar;
    printf("  %d ", bar.value());   //you get value of bar.val
}

printf不会调用你的任何运算符吧(包括转换运算符),所以这些对你没有帮助。即使你有operator int()你仍然应该这样写:

    printf("  %d ", (int)bar);   //you get value of bar.val

那不是更好看。甚至:

    printf("  %d ", +bar);   //you get value of bar.val

最令人困惑。

于 2012-09-08T21:33:58.470 回答
2

不,这是不可能的。

首先,逗号运算符在这里不适用,因为逗号用于分隔 printf 参数,它优先于用作运算符的逗号。

添加转换运算符没有帮助,因为 printf 的声明是

printf(const char *,...);

这意味着编译器不知道参数应该是什么类型(除了第一个),因此它不会进行任何转换。

于 2012-09-08T21:42:30.180 回答