Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指向成员的指针 在下面的代码中考虑语句:-“int b::*bPM;”_C++_Pointers_Pointer To Member - Fatal编程技术网

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()
}
这允许动态访问函数或变量

  • 您还可以在类的工厂中使用它来设置行为
否则,您将如何设置特定算法的行为(参见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);
  // ...
}
模板
类链接列表{
公众:
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);
  // ...
}