当我尝试编译代码时: (注意: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”选项仅用于编译。
答案 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()
。