在下面的代码中考虑语句:-“int B::*bpm;”
class B
{
public :
int bi;
};
class D : public B
{
};
int main()
{
D obj;
int B::*bpm;
bpm = &B::bi;
obj.*bpm = 1;
return 0;
}
*何时在设计/代码中使用“指向成员的指针”来改进我的设计/编码实践。**
在下面的代码中考虑语句:-“int B::*bpm;”
class B
{
public :
int bi;
};
class D : public B
{
};
int main()
{
D obj;
int B::*bpm;
bpm = &B::bi;
obj.*bpm = 1;
return 0;
}
*何时在设计/代码中使用“指向成员的指针”来改进我的设计/编码实践。**
STL的一个例子可能会有所帮助。
然后谈到设计/编码实践,对我来说,使用“指向成员的指针”来访问您的成员并不是一个好的设计,这些成员无论如何都是公开的并且可以以更明显的方式访问。
当多个成员需要类似的功能时,有时可以使用指向成员的指针来避免代码重复。另一种方法是使用枚举来识别成员并将它们存储为数组。
struct Foo
{
float a;
float b;
};
void Interpolate(const Foo &x, const Foo &y, float f, int Foo::*member)
{
return x.*member*(1-f)+y.*member*f;
}
int main()
{
Foo x,y;
float ia = Interpolate(x,y,0.5,&Foo::a);
float ib = Interpolate(x,y,0.5,&Foo::b);
}
这只是示例,插值是简短而简单的,但是一旦类似的功能很复杂,这将是非常有益的。
指向成员的指针与指向函数的指针具有相似的用途。当你需要它们时(在实践中很少见),你会知道的。
我之前遇到的一个可能的用例是使用模板专门针对某些行为的算法,其唯一目标是不重复自己:
struct foo
{
double f1(double);
...
double fn(double);
template <double (foo::*)(double)> double some_algorithm(...);
};
然后你使用a.some_algorithm<a::&fi>(...)
.
如果您查看 Stroustrup 的示例,我认为您可以看到指向成员类型的指针的强大功能:
class Interface {
public:
virtual start() = 0;
virtual stop() = 0;
virtual pause() = 0;
virtual resume() = 0;
virtual ~Interface() { }
}
typedef void (Interface::*P_MEM) (); // pointer to member type
map<string, Interface*> variable;
map<string, P_MEM> operation;
void call_member( string var, string oper )
{
(variable[var]->*operation[oper])(); // var.oper()
}
这允许动态访问函数或变量。
您还如何设置某个算法的行为(参见 Alexandre 的示例)?
指向成员的指针对于侵入性列表很有用
template<typename N, N *N::*nextp>
class LinkedList {
public:
LinkedList()
:head(0)
{ }
void add(N *item) {
item->*nextp = head;
head = item;
}
N *gethead() { return head; }
private:
N *head;
};
struct Node {
int data;
Node *next;
};
int main() {
LinkedList<Node, &Node::next> n;
Node a1 = { 1 };
Node a2 = { 2 };
n.add(&a2);
n.add(&a1);
// ...
}
我不会太担心指向成员的指针。在超过 15 年的 C++ 中,我使用过一次,大约十年前。
语言中已经内置的功能(即虚函数)使您不必手动摆弄成员指针。