如何实现回调函数

时间:2021-12-14 16:15:01
类SpotList有一个private的vector
class SpotList
{
........
private:
vector <spot> _list;
};

还有一个Robot类想对某个SpotList的实例中的vector进行const访问,读取信息到自己的实例里面.

原来的实现是SpotList直接返回vector的const引用.现在如果要在SpotList里用for_each作为公共遍历的实现,如何设计能使Robot类的某个成员函数能作为for_each的回调,或者有其他比较好的实现.多谢各位大虾的指教.

10 个解决方案

#1


友元?

不知道你想干什么

#2


呃,如果你肯用boost,就简单了
for_each(_list.begin(), _list.end(), bind(&Robot::函数名, Robot对象, _1));

如果你手头有《STL源码剖析》,你得把Robot的那个读信息的函数写成static的函数,其第一个参数为Robot &。
for_each(_list.begin(), _list.end(), bind1st(ptr_fun(&Robot::static函数名), Robot对象名);

所以,估计你还是老老实实用for循环吧。

#3


友元可以解决一个外部类访问的问题,关键是SpotList不会知道某时刻会有几多外部类需要访问它.我设计的是list只是存储和暴露一个回调接口,任何需要的外部类都可以从这个回调接口访问.

#4


没有用过boost,谢谢taodm(taodm)的提示,到最后会考虑一下.对bind不太了解,会不会写成static成员函数就不能访问自己实例的非static成员了?

#5


class SpotList
{
........

template<class T>
void do(T& t)
{
 std::for_each(_list.begin(), _list.end(), t);
}

private:
vector <spot> _list;
};

Robot 调用的时候先用 std::mem_fun, 再用 std::bind 把 this 指针绑上去

#6


所以,要这个static函数的第一个参数是Robot &呀。
在这个static函数里,把调用传递到真正的robot对象身上。
stl的mem_fun是只能绑定在无参数的成员函数身上的。
要么,你仿mem_fun写一个可以接受参数的mem_fun_1para类。

#7


"Robot 调用的时候先用 std::mem_fun, 再用 std::bind 把 this 指针绑上去"

能不能具体写下

#8


友元可以解决一个外部类访问的问题,关键是SpotList不会知道某时刻会有几多外部类需要访问它.我设计的是list只是存储和暴露一个回调接口,任何需要的外部类都可以从这个回调接口访问.
——————————————————————————————————————————
这样吧:
struct IRobot  // “任何需要的外部类”,必须派生自IRobot
{
virtual dispose(const spot& obj) = 0;
};

class Robot : public IRobot
{
public:
virtual dispose(const spot& obj);
}

class Robot1 : public IRobot // “任何需要的外部类”,必须派生自IRobot
{
public:
virtual dispose(const spot& obj);
}

class SpotList
{
public:
void registerVisitor(IRobot* robot)
{
  _robot = robot;
}
private:
vector <spot> _list;
IRobot* _robot;
};

#9


参照各位大牛的提示,我自己写出了一个实现的demo
typedef int spot;
typedef vector<spot> spots;

class SpotList
{
public:
SpotList();
template<typename R, typename T>
void for_each_elem(T& t, R (T::*f)(const spot&))
{
spots::const_iterator iter;
for (iter = m_value.begin(); iter != m_value.end(); advance(iter, 1))
{
(t.*f)(*iter);
}
};
private:
spots m_value;
};

class Robot
{
public:
void caller_back(const spot& value);
void Do();
private:
SpotList spl;
spot i;
};

SpotList::SpotList()
{
m_value.push_back(7);
m_value.push_back(6);
m_value.push_back(3);
m_value.push_back(76);
m_value.push_back(5);
m_value.push_back(0);
}

void Robot::caller_back(const spot& value)
{
this -> i = value;
cout<<this -> i<<endl;
}

void Robot::Do()
{
spl.for_each_elem(*this, &Robot::caller_back);
}

int main()
{
Robot r;
r.Do();
return 0;
}

只是初步实现,请各位大虾指正

#10


template<typename R, typename T>
void for_each_elem(T& t, R (T::*f)(const spot&))
——————————————————————————————————————————
你用模板也行。
其实,还是要求了T必须又一个以const spot&为参数的函数。只不过函数名可以不必一致。
虚函数还是模板,还需多加考虑……

#1


友元?

不知道你想干什么

#2


呃,如果你肯用boost,就简单了
for_each(_list.begin(), _list.end(), bind(&Robot::函数名, Robot对象, _1));

如果你手头有《STL源码剖析》,你得把Robot的那个读信息的函数写成static的函数,其第一个参数为Robot &。
for_each(_list.begin(), _list.end(), bind1st(ptr_fun(&Robot::static函数名), Robot对象名);

所以,估计你还是老老实实用for循环吧。

#3


友元可以解决一个外部类访问的问题,关键是SpotList不会知道某时刻会有几多外部类需要访问它.我设计的是list只是存储和暴露一个回调接口,任何需要的外部类都可以从这个回调接口访问.

#4


没有用过boost,谢谢taodm(taodm)的提示,到最后会考虑一下.对bind不太了解,会不会写成static成员函数就不能访问自己实例的非static成员了?

#5


class SpotList
{
........

template<class T>
void do(T& t)
{
 std::for_each(_list.begin(), _list.end(), t);
}

private:
vector <spot> _list;
};

Robot 调用的时候先用 std::mem_fun, 再用 std::bind 把 this 指针绑上去

#6


所以,要这个static函数的第一个参数是Robot &呀。
在这个static函数里,把调用传递到真正的robot对象身上。
stl的mem_fun是只能绑定在无参数的成员函数身上的。
要么,你仿mem_fun写一个可以接受参数的mem_fun_1para类。

#7


"Robot 调用的时候先用 std::mem_fun, 再用 std::bind 把 this 指针绑上去"

能不能具体写下

#8


友元可以解决一个外部类访问的问题,关键是SpotList不会知道某时刻会有几多外部类需要访问它.我设计的是list只是存储和暴露一个回调接口,任何需要的外部类都可以从这个回调接口访问.
——————————————————————————————————————————
这样吧:
struct IRobot  // “任何需要的外部类”,必须派生自IRobot
{
virtual dispose(const spot& obj) = 0;
};

class Robot : public IRobot
{
public:
virtual dispose(const spot& obj);
}

class Robot1 : public IRobot // “任何需要的外部类”,必须派生自IRobot
{
public:
virtual dispose(const spot& obj);
}

class SpotList
{
public:
void registerVisitor(IRobot* robot)
{
  _robot = robot;
}
private:
vector <spot> _list;
IRobot* _robot;
};

#9


参照各位大牛的提示,我自己写出了一个实现的demo
typedef int spot;
typedef vector<spot> spots;

class SpotList
{
public:
SpotList();
template<typename R, typename T>
void for_each_elem(T& t, R (T::*f)(const spot&))
{
spots::const_iterator iter;
for (iter = m_value.begin(); iter != m_value.end(); advance(iter, 1))
{
(t.*f)(*iter);
}
};
private:
spots m_value;
};

class Robot
{
public:
void caller_back(const spot& value);
void Do();
private:
SpotList spl;
spot i;
};

SpotList::SpotList()
{
m_value.push_back(7);
m_value.push_back(6);
m_value.push_back(3);
m_value.push_back(76);
m_value.push_back(5);
m_value.push_back(0);
}

void Robot::caller_back(const spot& value)
{
this -> i = value;
cout<<this -> i<<endl;
}

void Robot::Do()
{
spl.for_each_elem(*this, &Robot::caller_back);
}

int main()
{
Robot r;
r.Do();
return 0;
}

只是初步实现,请各位大虾指正

#10


template<typename R, typename T>
void for_each_elem(T& t, R (T::*f)(const spot&))
——————————————————————————————————————————
你用模板也行。
其实,还是要求了T必须又一个以const spot&为参数的函数。只不过函数名可以不必一致。
虚函数还是模板,还需多加考虑……