请检查以下代码。为什么这是错误的以及如何解决?谢谢。
class A
{
public:
class B
{
public:
B(int(*cf)())
{
f = cf;
}
int (*f)();
};
B *b;
A()
{
b = new B(this->a);
}
int a()
{
}
};
int main()
{
A a;
}
编译错误:
答案 0 :(得分:1)
如果您绝对需要通过指针调用函数,则需要使用指向成员函数的指针而不是指向函数的指针。指向成员函数的指针具有不同的声明语法,其中包括函数所属的类类型。在您的情况下,参数声明看起来像int (A::*cp)()
。您还需要将f
成员变量的声明更改为int (A::*f)()
。
为了调用指向成员函数的指针,您需要有一个指向该函数所属类型的对象的指针。您还需要使用指向成员运算符的指针之一; ->*
或.*
void call(A* c, int (A::*f)())
{
(c->*f)(); // call member function through pointer
}
由于运算符的优先顺序,需要额外的括号集。
以下代码包含使用指向成员函数的指针所需的更改。
class A
{
public:
class B
{
public:
// Take a pointer to member function.
B(int(A::*cf)())
{
f = cf;
}
void call(A* c)
{
(c->*f)();
}
int (A::*f)(); // pointer to member function
};
B *b;
A()
{
b = new B(&A::a);
}
int a()
{
return 0;
}
};
int main()
{
A a;
a.b->call(&a);
}
我还建议您考虑使用std::function
和std::bind
(或者如果您没有C ++ 11编译器,则使用它们的Boost等效项。)
答案 1 :(得分:0)
使用C ++时,首先不要使用函数指针。
有一种更简单,更精确的解决方案 - 界面。
即
class Interface {
public:
virtual int CallMe() = 0;
};
class B : public Interface { int CallMe() { return 5; };
class A : public Interface {
private:
Interface *m_i = 0;
public:
A(Interface *i) : m_i(i) { }
A() : m_i(this) { };
void DoIt() { cout << m_i->CallMe() << endl; }
int CallMe() { return 8; }
};
int main() {
A a(new B); // Coult be any object that implements Interface (as yes it is a memory leak
A aa();
a.DoIt(); // Will print 5
aa.DoIt(); // WIll print 8
return 0;
}