调用过载运算符 - >在编译时解决?

时间:2010-05-25 14:57:30

标签: c++ operator-overloading

当我尝试编译代码时: (注意:func和func2不是拼写错误)

struct S
{
    void func2() {}
};

class O
{
public:
    inline S* operator->() const;
private:
    S* ses;
};

inline S* O::operator->() const
{
    return ses;
}

int main()
{
    O object;
    object->func();
    return 0;
}

报告了编译错误:

D:\code>g++ operatorp.cpp -S -o operatorp.exe
operatorp.cpp: In function `int main()':
operatorp.cpp:27: error: 'struct S' has no member named 'func'

似乎调用了“operator->”的重载函数在编译期间完成?我添加了“-S”选项仅用于编译。

5 个答案:

答案 0 :(得分:10)

是的,它被视为普通的函数调用,它只是由重载的运算符调用。编译器在编译时检查一切是否有效。 C ++与动态语言不同,如果p->mynonexistantfunction()是函数的有效名称,它等待运行时才能计算出来,如果函数名不存在,编译器将在编译时拒绝代码。

在这种情况下,它看起来像一个拼写错误,S有一个函数func2()但你的代码调用func()

答案 1 :(得分:3)

在struct S中你声明了func2(),但在main中,你试着调用func()。

int main() { O object; object->func2(); return 0; }

答案 2 :(得分:2)

是的,编译器会根据其结果检查运算符。

在这种情况下,如果您有,例如,

S* foo() { ... }

(foo())->func();

结果会一样。

答案 3 :(得分:2)

在C ++语言中,您无法在运行时按名称选择类成员。类成员选择(通过直接成员名称)始终在编译时完成。没有办法解决它。

如果要在运行时实现成员选择,则唯一可以使用的是运算符.*->*(前者 - 不可重载)。但是,这些内置形式的运算符需要将指针指向成员作为右手操作数。如果要按名称选择某些内容(作为字符串),可以重载->*以使其采用不同的参数类型,但无论如何,您必须手动实现从字符串到实际成员的映射。但是,对于成员函数(与数据成员相对),这通常非常棘手。

答案 4 :(得分:1)

对于用户定义的类型,

object->func()只是object->operator->()->func()的语法糖。由于O::operator->()产生S*,因此需要在编译时存在方法S::func()