我试图通过传递函数指针来实现这样的工作。我知道你可以将第一个类的指针传递给第二个类,然后通过指针获取第二个类的成员函数。但我不希望第二堂课依赖于知道第一堂课是谁。这更像是我想要实现这一目标的编码风格。感谢
//////////////////////////////////////////////////
class Second
{
public:
Second::Second(void (*SecondTriggered)(void));
};
Second::Second(void (*SecondTriggered)(void))
{
SecondTriggered();
}
//////////////////////////////////////////////////
class First
{
public:
First::First();
void SecondTriggered();
Second *second;
};
First::First(){
printf("first class was created");
second = new Second(SecondTriggered);
}
void First::SecondTriggered(){
printf("second class was created and responded");
}
/////////////////
int main()
{
First *first = new First();
}
我收到此错误:
error C3867: 'First::SecondTriggered': function call missing argument list;
use '&First::SecondTriggered' to create a pointer to member
任何想法。
答案 0 :(得分:3)
您正在尝试传递一个非静态类成员,其中需要一个独立的函数。要做你正在尝试的事情,你将不得不做以下的事情:
class Second
{
public:
Second::Second(void (*SecondTriggered)(void*), void *arg);
};
Second::Second(void (*SecondTriggered)(void*), void *arg)
{
SecondTriggered(arg);
}
//////////////////////////////////////////////////
class First
{
public:
First::First();
static void SecondTriggered(void *arg);
Second *second;
void DoSomething();
};
First::First(){
printf("first class was created");
second = new Second(&SecondTriggered, this);
}
void First::SecondTriggered(void *arg){
printf("second class was created and responded");
static_cast<First*>(arg)->DoSomething();
}
void First::DoSomething(){
printf("first class did something");
}
/////////////////
int main()
{
First *first = new First();
}
答案 1 :(得分:2)
请记住,指向成员函数和函数指针的指针是非常不同的。您必须有一个对象来调用指向成员函数的指针。如果你想使用指向成员函数的指针,下面的代码可以工作(我只显示了使代码工作的语法。我建议在使用指向成员函数的指针之前理解C ++概念):
#include <stdio.h>
//////////////////////////////////////////////////
class First; // Forward declaration needed
class Second
{
public:
Second(void (First::*SecondTriggered)(void), First& f);
};
Second::Second(void (First::*SecondTriggered)(void), First& f)
{
(f.*SecondTriggered)();
}
//////////////////////////////////////////////////
class First
{
public:
First();
~First() { delete second;} // Fix memory leak
void SecondTriggered();
Second *second;
};
First::First(){
printf("first class was created\n"); // What are you using printf in C++?
second = new Second(&First::SecondTriggered, *this);
}
void First::SecondTriggered(){
printf("second class was created and responded\n");
}
/////////////////
int main()
{
First first; // No reason to use new here
}
请阅读this faq了解详情。
答案 2 :(得分:2)
您应该阅读How do I implement a callback in C++?并特别注意对Observer Pattern的引用。如果你有两个这样紧密耦合的类,那么你可能想重新考虑你的设计,因为测试它们很快就会成为一场噩梦。
那就是说,这是如何完成你开始的实现......
#include <iostream>
class First;
// Typedefs make this much more readable: http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.5
typedef void (First::*SecondTriggeredCallback)(void);
// And macros make the call much more readable: http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.6
#define CALL_MEMBER_FN(object, ptrToMember) ((object).*(ptrToMember))
class Second
{
public:
// You'll also need an *instance* of the First class
Second(SecondTriggeredCallback SecondTriggered, First& first)
{
CALL_MEMBER_FN(first, SecondTriggered)();
}
};
class First
{
private:
Second *second;
public:
First()
{
std::cout << "first class was created" << std::endl;
second = new Second(&First::SecondTriggered, *this);
}
~First()
{
delete second;
}
void SecondTriggered()
{
std::cout << "second class was created and responded" << std::endl;
}
};
int main()
{
First first;
}
这是一个使用模板删除耦合的版本:
#include <iostream>
// Macros make the call much more readable: http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.6
#define CALL_MEMBER_FN(object, ptrToMember) ((object).*(ptrToMember))
template <class T>
struct Second
{
// Typedefs make this much more readable: http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.5
typedef void (T::*SecondTriggeredCallback)(void);
// You'll also need an *instance* of the "T" class
Second(SecondTriggeredCallback SecondTriggered, T& t)
{
CALL_MEMBER_FN(t, SecondTriggered)();
}
};
class First
{
public:
First()
:second(NULL)
{
std::cout << "first class was created" << std::endl;
second = new Second<First>(&First::SecondTriggered, *this);
}
~First()
{
delete second;
}
void SecondTriggered()
{
std::cout << "second class was created and responded" << std::endl;
}
private:
First(const First&);
First& operator =(const First&);
Second<First>* second;
};
int main()
{
First first;
}
答案 3 :(得分:1)
您也可以考虑传递一个函数对象:
class t_func {
protected:
t_func() {
}
virtual ~t_func() {
}
public:
virtual void operator()() = 0;
private:
t_func(const t_func&) = delete;
t_func& operator=(const t_func&) = delete;
};
class Second {
public:
Second(t_func& func);
};
Second::Second(t_func& func) {
func();
}
class First {
public:
First();
private:
void SecondTriggered();
Second* second;
};
First::First() {
printf("first class was created\n");
class t_trigger : public t_func {
public:
t_trigger(First& pFirst) : t_func(), first(pFirst) {
}
virtual void operator()() {
return first.SecondTriggered();
}
private:
First& first;
};
t_trigger trig(*this);
second = new Second(trig);
}
void First::SecondTriggered() {
printf("second class was created and responded\n");
}
int main() {
First* first = new First();
delete first;
return 0;
}