简体   繁体   English

指向类的私有数据成员的指针

[英]Pointer to a class's private data member

Consider a class card which has two public members, int suit and int value , and a template function that sorts an array of cards by the member I pass through a pointer-to-member, like this: 考虑一个具有两个公共成员的类card ,该成员具有int suitint value ,以及一个模板函数,该函数按我通过指向成员的指针传递的成员对卡数组进行排序,如下所示:

//class card with public members
class card{
 public:
    int suit;
    int value;
};   

//sorting algorithm
template<typename m_pointer, typename iterator, typename Functype>
void sort_array(m_pointer member, iterator begin, iterator end, Functype pred){
   iterator iter1=begin;
   while(iter1!=end && ++iter1!=end){
    iterator iter2=iter1;
    while(iter2!=begin){
        iterator iter3=iter2;
        --iter3;
        //here i use the pointer-to-member to sort the cards
        if(pred((*iter3).*member, (*iter2).*member)){
            std::swap(*iter3, *iter2);
        }
        else break;
        --iter2;
    }
  }
}

int main(){
  card array[3]={{3,1},{2,3},{4,5}};
  //let's sort the cards by the suit value in a decreasing order
  sort(&card::suit, array, array+3, [](int a, int b){return a<b;});
}

If the card member suit is public there's obviously no problem, but what actually i didn't expected is that the same code doesn't give any trouble even if i declare suit or value as private members. 如果卡部件suit是公众有明显的没有问题,但究竟是什么,我没有预见的是,相同的代码不给任何麻烦,即使我宣布suitvalue的私有成员。

class card{
   int suit;
   int value;
  public://adding this for clarity, read forward
   int* pointer_to_suit();    
};

From what I know, I shouldn't be able to access private members from outside the class, and the only way to pass a pointer-to-member to a private member is through a member function which returns the member address, like this for example: 据我所知,我不应该从类外部访问私有成员,而将指向成员的指针传递给私有成员的唯一方法是通过返回成员地址的成员函数,例如例:

//function member of the class card
int* card::pointer_to_suit(){
   return &suit;
}

So, why is it possible that the code above (the one with the template) works? 那么,为什么上面的代码(带有模板的代码)可以工作?

EDIT: Ok, the code above doesn't compile on it's own, but for some reason the following code compile fine to me. 编辑:好的,上面的代码不是自己编译的,但是出于某种原因,下面的代码对我来说很好。 I'll post the whole code since I've no idea where the trick for it to work might be, sorry for the mess: 我将发布整个代码,因为我不知道它可能起作用的诀窍在哪儿,对此一团糟:

template<typename m_pointer, typename iterator, typename Functype>
void sort_array(m_pointer member, iterator begin, iterator end, Functype pred){
 iterator iter1=begin;
while(iter1!=end && ++iter1!=end){
    iterator iter2=iter1;
    while(iter2!=begin){
        iterator iter3=iter2;
        --iter3;
        if(pred((*iter3).*puntatore, (*iter2).*puntatore)){
            std::swap(*iter3, *iter2);
        }
        else break;
        --iter2;
    }
  }
}


class card{
   int suit;
   int value;
public:
card(): suit(0), value(0) {} 
card(int a, int b): suit(a), value(b){}
bool operator==(card a){return (suit==a.get_s() && value==a.get_v());}
bool operator!= (card a){return !(*this==a);}

void set_values(int a, int b){suit=a; value=b;}
int get_v(){return value;}
void set_v(int v){value=v;}
int get_s(){return suit;}
void set_s(int s){suit=s;}
double points_card();
};


template<typename iterator>
void ordina(iterator begin, iterator end, short (&suit)[4]){

for(int i=0; i<4; i++) suit[i]=0;

iterator it1=begin;
while(it1!=end){
    if((*it1).get_s()==1) suit[0]+=1;
    else if((*it1).get_s()==2) suit[1]+=1;
    else if((*it1).get_s()==3) suit[2]+=1;
    else if((*it1).get_s()==4) suit[3]+=1;
    ++it1;
}

sort_array(&carte::suit, begin, end, [](char a, char b){
    if(b==0) return false;
    else if(a==0) return true;
    return (a>b);
});

sort_array(&carte::value, begin, begin+suit[0], [](int a, int b){return (a<b);});
sort_array(&carte::value, begin+suit[0], begin+suit[0]+suit[1], [](int a, int b){return (a<b);});
sort_array(&carte::value, begin+suit[0]+suit[1], begin+suit[0]+suit[1]+suit[2], [](int a, int b){return (a<b);});
sort_array(&carte::value, begin+suit[0]+suit[1]+suit[2], begin+suit[0]+suit[1]+suit[2]+suit[3],[](int a, int b){return (a<b);});
}

int main(){
 card array[5]={{2,3},{1,2},{3,4},{4,5},{3,2}};
 short suits[4]={1,1,2,1};
 ordina(array, array+5, suits);
 return 0;
}

EDIT 2: Yes, it runs http://coliru.stacked-crooked.com/a/d1795f0845770fcb . 编辑2:是的,它运行http://coliru.stacked-crooked.com/a/d1795f0845770fcb Please note that the code here is not translated and there are some lines i didn't add for brevity. 请注意,此处的代码未翻译,为简洁起见,我没有添加一些行。

EDIT 3: As mentioned in Barry answer https://stackoverflow.com/a/35978073/5922196 , this is a gcc compiler bug. 编辑3:如Barry回答https://stackoverflow.com/a/35978073/5922196所述 ,这是gcc编译器错误。 I used g++ 4.9.2 and this bug is still unresolved 我使用g++ 4.9.2 ,但此错误仍未解决

Congratulations, you found a bug in gcc! 恭喜,您在gcc中发现了一个错误! Here is a minimally reproduced example. 这是最小复制的示例。 Note that when we say minimal , we really do mean minimal . 请注意,当我们说最小时 ,我们实际上的意思是最小 I found this by just repeatedly deleting most of your lines of code. 我是通过重复删除大多数代码行来发现这一点的。 Also, always include things which compiler you used. 另外,请始终包括您使用的编译器。 Would've helped. 会有所帮助的。

gcc compiles this: gcc编译如下:

class X {
    int mem;
};

template <class T>
auto foo(T) {
    return &X::mem;
}

int main() {
    auto p = foo(0);
}

clang does not. 铛没有。 clang is right. 铛是正确的。 This is gcc bug 41437 . 这是gcc错误41437

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 指向类的私有数据成员的指针 - Pointer to private data member of a class 当它是 class 数据成员时,如何调用指向成员 function 的指针? - How to invoke pointer to member function when it's a class data member? 指向 class 数据成员“::*”的指针 - Pointer to class data member "::*" 指向类数据成员的指针 - Pointer to class data member 私有成员函数,该函数需要指向同一类中私有成员的指针 - Private member function that takes a pointer to a private member in the same class 将私有方法类成员作为函数的指针传递 - passing private method class member as pointer to a function 如果是 class 的私有数据成员并且我们创建该 class 的两个对象,那么指向 int 数据类型的指针是什么? - What is a pointer of int data type pointing at if is a private data member of a class and we create two objects of that class? 为什么c ++允许通过指针访问类的私有成员? - Why does c++ allow access to a class's private member through a pointer? 指针和指向类数据成员的指针的抽象 - Abstraction of pointer and pointer to class data member 带有私人成员的类是带有基类指针的模板吗? - Class With A Private Member Being A Template With A Base Class Pointer?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM