指向类的私有数据成员的指针
Pointer to a class's private data member
考虑一个类card
,它有两个公共成员,int suit
和 int 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;});
}
如果卡会员suit
是公开的,显然没有问题,但实际上我没想到的是,即使我将suit
或value
声明为私有会员,相同的代码也不会带来任何麻烦。
class card{
int suit;
int value;
public://adding this for clarity, read forward
int* pointer_to_suit();
};
据我所知,我应该无法从类外部访问私有成员,并且将指向成员的指针传递给私有成员的唯一方法是通过返回成员地址的成员函数,例如:
//function member of the class card
int* card::pointer_to_suit(){
return &suit;
}
那么,为什么上面的代码(带有模板的代码)可以工作呢?
编辑:好的,上面的代码不能自行编译,但由于某种原因,以下代码对我来说编译得很好。我将发布整个代码,因为我不知道它工作的诀窍可能在哪里,很抱歉造成混乱:
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;
}
编辑2:是的,它运行 http://coliru.stacked-crooked.com/a/d1795f0845770fcb。请注意,此处的代码未翻译,为了简洁起见,我没有添加一些行。
编辑3:如Barry回答 https://stackoverflow.com/a/35978073/5922196 中所述,这是一个gcc
编译器错误。我用过g++ 4.9.2
,这个错误仍未解决
恭喜,您在 gcc 中发现了一个错误!这是一个最小复制的示例。请注意,当我们说最小时,我们确实意味着最小。我通过反复删除您的大部分代码行来发现这一点。此外,始终包括您使用的编译器的内容。会有所帮助。
GCC 编译了这个:
class X {
int mem;
};
template <class T>
auto foo(T) {
return &X::mem;
}
int main() {
auto p = foo(0);
}
叮当没有。叮当是对的。这是 gcc 错误 41437。
相关文章:
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 使用指针访问数组中的对象数据成员
- 共享 C++ 的数据成员指针
- C++数据成员:值与指针
- 如何使用数据成员填充派生类的对象到基类的指针数组中
- 如何在C++中使用类对象访问指针数据成员
- 将指向数据成员的指针传递给 std::invoke 时有哪些用例和有用性?
- 通过指针算法访问结构数据成员
- 如何强制实施有关指针数据成员的常量正确性
- 类数据成员指针的非类型模板参数包无法使用 gcc 编译
- constexpr 偏移量,带有指向成员数据的指针
- 指向未由对象地址初始化的对象的指针如何将值分配给类的数据成员
- 将数据成员的指针传递给基类构造函数是否安全?
- 虚拟指针大小因类数据成员而异
- "new"不会将内存分配给作为类的数据成员的指针
- 关于Lambdas,转换以功能指针以及私人数据成员的可见性
- 向上转换指向数据成员及其多态行为的指针
- 指向数据成员转换的 Constexpr 指针
- 关于C++中指向数据成员的指针的一些混淆
- C 细分故障访问类数据成员,而无需明确使用指针