C++ 指向成员的指针 在下面的代码中考虑语句:-“int b::*bPM;”
*何时在设计/编码中使用“指向成员的指针”来改进我的设计/编码实践。C++ 指向成员的指针 在下面的代码中考虑语句:-“int b::*bPM;”,c++,pointers,pointer-to-member,C++,Pointers,Pointer To Member,*何时在设计/编码中使用“指向成员的指针”来改进我的设计/编码实践。 **谈到设计/编码实践,那么,对我来说,使用“指向成员的指针”访问您的成员不是一个好的设计,这些成员无论如何都是公开的,并且可以以更明显的方式访问。我不太担心指向成员的指针。在C++的15年里,我大约十年前使用过一次。 语言中已经内置的特性(即虚拟函数)可以防止您手动处理成员指针 当多个成员需要类似的功能时,有时可以使用指向成员的指针来避免代码重复。另一种方法是使用enum标识成员并将其存储为数组 struct Foo {
**谈到设计/编码实践,那么,对我来说,使用“指向成员的指针”访问您的成员不是一个好的设计,这些成员无论如何都是公开的,并且可以以更明显的方式访问。我不太担心指向成员的指针。在C++的15年里,我大约十年前使用过一次。
语言中已经内置的特性(即虚拟函数)可以防止您手动处理成员指针 当多个成员需要类似的功能时,有时可以使用指向成员的指针来避免代码重复。另一种方法是使用enum标识成员并将其存储为数组
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(...);
};
structfoo
{
双f1(双);
...
双fn(双);
模板双素算法(…);
};
然后使用
a.some_算法(…)
如果您查看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()
}
类接口{
公众:
虚拟开始()=0;
虚拟停止()=0;
虚拟暂停()=0;
虚拟恢复()=0;
虚拟~Interface(){}
}
typedef void(接口::*P_MEM)(;/)指向成员类型的指针
映射变量;
地图操作;
void call_成员(字符串变量、字符串操作)
{
(变量[var]->*操作[oper])();//var.oper()
}
这允许动态访问函数或变量
- 您还可以在类的工厂中使用它来设置行为
- 您可以编写一个行为类,但随后必须为每个函数创建一个类,为所有类创建另一个接口,以便您的算法调用该类。如果类中没有任何数据,这不是一种浪费吗
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);
// ...
}
模板
类链接列表{
公众:
LinkedList()
:头(0)
{ }
无效添加(N*项){
项目->*nextp=头;
头=项目;
}
N*gethead(){return head;}
私人:
N*头部;
};
结构节点{
int数据;
节点*下一步;
};
int main(){
链接列表n;
节点a1={1};
节点a2={2};
n、 添加(&a2);
n、 添加(&a1);
// ...
}
请修复您的格式设置。代码需要加四个空格作为前缀。?您已经在使用“指向成员的指针”一个好问题可能是“何时使用”指向成员的指针!这个问题对我来说似乎很模糊,而且表述得很糟糕。@chubsdad:很抱歉,我的意思是“何时使用‘指向成员的指针’”。那时你从未使用过MFC。@Alexandre:不,我没有。对此我很高兴<代码>:)@Alexandre:我不确定。我可能不会仅仅因为一份MFC的工作而拒绝一份工作,但这会对决策过程产生非常强烈的负面影响<代码>:)@sbi:MFC正在被根除的路上,所以你应该很安全。我从内心深处讨厌MFC和ATL,但我被雇来做有趣的数学,但到处都是MFC和COM层…@Alexandre:我和你有同感。来,喝杯虚拟啤酒<代码>:)是的,STL确实缺乏这种内置功能。例如,在成对的第一个元素的序列上使用算法是很麻烦的。让系统中的其他实体(名称空间函数)处理“Foo”的(假定是私有的)数据是一个好主意吗?这只是一个概念示例。实际上,要么插值函数是一个成员函数,要么通过成员函数访问a和b,并提供指向成员函数的指针。
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);
// ...
}