指向成员数据问题的指针

编程入门 行业动态 更新时间:2024-10-26 12:28:57
本文介绍了指向成员数据问题的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

以下类包含一系列 值的起点和终点。范围可以具有从开始和结束的相对顺序暗示的方向,或者可以没有方向。 IOW 如果start大于end,而direction == true,那么范围 有反方向。如果direction == false,起点是 总是小于终点。 例如,为了使两个范围的交集变得更容易,我还想要保持标准化的价格。开始和结束的开始<结束 即使真正的开始大于结束。由于模板 参数E(对于元素类型)可以是任何东西,我不想 生成可能昂贵的起始和结束元素副本如果 它们是用户定义的类型。因此,我决定尝试将这个 信息存储在指向会员的指针中。 大部分时间这都可行。但对于负向 方向的范围,虽然elem_ptr成员显然指向正确的成员(即反转),当我取消引用它们时,我得到了 错误数据:例如this-> * m_pNormalizedStart将返回m_start而不是m_end的,尽管调试器为m_pNormalizedStart显示& Range< int,int> :: m_end" 我知道我可以使用成员函数返回规范化数据 并且只需要将m_start与m_end进行比较。这不会是一个问题, 因为它可以内联,但我想知道一般情况下是否使用 指向这样的成员就可以了。 有什么腥的东西吗?关于我如何在构造函数中设置成员指针 ?我知道在成员初始化时,对象还没有完全构建起来。但是,会员数据首先被初始化 因此应该有一个有效的地址。 我也认为编译器可能正在处理 成员喜欢静态数据(因为这是设置他们的 值的语法)并在创建一个新的Range时使用 不同的方向覆盖它们。但是,我假设每个Range对象都会有一组不同的成员指针。也许这不是有效的 假设? 我希望我只是犯了一些其他愚蠢的错误,但我看了 很难,还没有找到任何东西。我不认为这是一个编译器错误 ,因为我在运行我在 GCC和Borland上编译的测试代码时会得到相同的行为。 这是一些骨架代码: //声明: 模板< typename E,typename D = E> 类范围 { typedef E Range :: * elem_ptr; public: 范围< E,D> ::范围() :m_start() ,m_end() ,m_directed(false ) ,m_pNormalizedStart(& Range :: m_start) ,m_pNormalizedEnd(& Range :: m_end){;} 范围< E,D> ::范围(const E& startElem ,const E& endElem ,bool导演) :m_start(导演? startElem :( startElem> endElem?endElem:startElem)) ,m_end(导演? endElem: (startElem< endElem?endElem:startElem)) ,m_directed(定向) ,m_pNormalizedS tart(m_start< = m_end? & Range :: m_start:& Range :: m_end) ,m_pNormalizedEnd(m_start< = m_end? & Range :: m_end:& Range :: m_start){;} //等等 私人: E m_start; E m_end; bool m_directed; elem_ptr m_pNormalizedStart; elem_ptr m_pNormalizedEnd; }; TIA - Bob Hairgrove No**********@Home

解决方案

2004年7月3日星期六16:40:45 +0200,Bob Hairgrove < wo ********* *****@to.know>写道: oops ...构造函数是从不同的文件中复制和粘贴的。 这是他们应该看的样子: template< typename E,typename D = E> class Range { typedef E Range :: * elem_ptr; public:范围():m_start(),m_end(),m_directed(false),m_pNormalizedStart(& Range :: m_start),m_pNormalizedEnd(& ; Range :: m_end){;} 范围(const E& startElem ,const E& endElem ,bool指示):m_start(指导) ? startElem :( startElem> endElem?endElem:startElem)),m_end(指示? endElem:(startElem< endElem?endElem:startElem)),m_directed (指示),m_pNormalizedStart(m_start< = m_end?& Range :: m_start:& Range :: m_end),m_pNormalizedEnd(m_start< = m_end? & Range :: m_end:& Range :: m_start){;} //等私人: E m_start; E m_end; bool m_directed; elem_ptr m_pNormalizedStart; elem_ptr m_pNormalizedEnd; };

- Bob Hairgrove No**********@Home

2004年7月3日星期六16:40:45 +0200,Bob Hairgrove < wo *********** ***@to.know>写道:

以下类包含一系列值的起点和终点。范围可以具有从开始和结束的相对顺序隐含的方向,或者可以没有方向。 IOW 如果start大于end,而direction == true,那么范围有反方向。如果direction == false,则起点始终小于终点。 为了使两个范围的交集更容易,例如,我也想要保持标准化的开始和结束的开始<结束即使真正的开始大于结束。由于模板参数E(对于元素类型)可以是任何东西,我不想生成可能昂贵的起始和结束元素副本,如果它们是用户定义的类型。因此,我决定尝试将这些信息存储在指向成员的指针中。 大部分时间这都可行。但是对于具有负方向的范围,虽然elem_ptr成员显然指向正确的成员(即反转),但当我取消引用它们时,我得到了错误的数据:例如this-> * m_pNormalizedStart将返回m_start而不是m_end,尽管调试器为m_pNormalizedStart显示& Range< int,int> :: m_end。 我知道我可以使用成员函数返回规范化数据并且只需要将m_start与m_end进行比较。这不会是一个问题,因为它可以内联,但我想知道一般情况下是否使用指向这样的成员就可以了。 是那里有腥的东西。关于我如何在构造函数中设置成员指针?我知道在成员初始化时对象还没有完全构建好;然而,成员数据首先被初始化,因此应该有一个有效的地址。 我还认为编译器可能会像静态数据那样处理指针。这是设置其值的语法,并在创建具有不同方向的新范围时覆盖它们。但是,我假设每个Range对象都有一组不同的指向成员的指针。也许这不是一个有效的假设吗? 我希望我只是犯了一些其他愚蠢的错误,但我看起来很难,但还没找到任何东西。我不认为这是一个编译器错误因为我在运行我在GCC和Borland上编译的测试代码时会得到相同的行为。 这是一些骨架代码:

为我工作,看不出有什么不对。 #include< iostream> 使用命名空间std; 模板< typename E,typename D = E> 类范围 { typedef E Range :: * elem_ptr; public: Range() :m_start() ,m_end() ,m_directed(false) ,m_pNormalizedStart(& Range :: m_start) ,m_pNormalizedEnd(&范围:: m_end){;} 范围(const E& startElem ,const E& endElem , bool导演) :m_start(导演? startElem :( startElem> endElem?endElem:startElem)) ,m_end(导演? endElem :( startElem< endElem?endElem:startElem)) ,m_directed(定向) ,m_pNormalizedStart(m_start< = m_end? & Range :: m_start:& Range :: m_end) ,m_pNormalizedEnd(m_start< = m_end? & Range :: m_end:& Range :: m_start){;} //等 void dump() { cout<< this-> * m_pNormalizedStart<< ''\ n''; cout<< this-> * m_pNormalizedEnd<< ''\ n''; } 私人: E m_start; E m_end; bool m_directed; elem_ptr m_pNormalizedStart; elem_ptr m_pNormalizedEnd; }; int main() { 范围< int> r(20,10,true); 范围< int> s(10,20,true); r.dump(); s.dump(); } 输出 10 20 10 20 john

2004年7月3日星期六16:40:45 +0200,Bob Hairgrove < wo ************** @ to.know>写道:

以下类包含一系列值的起点和终点。范围可以具有从开始和结束的相对顺序隐含的方向,或者可以没有方向。 IOW 如果start大于end,而direction == true,那么范围有反方向。如果direction == false,则起点始终小于终点。 为了使两个范围的交集更容易,例如,我也想要保持标准化的开始和结束的开始<结束即使真正的开始大于结束。由于模板参数E(对于元素类型)可以是任何东西,我不想生成可能昂贵的起始和结束元素副本,如果它们是用户定义的类型。因此,我决定尝试将这些信息存储在指向成员的指针中。

您可以使用普通指针,甚至可以使用引用。 john

The following class contains start and end points of a range of values. The range can have a direction which is implied from the relative order of start and end, or it can be without direction. IOW if start is greater than end, and direction == true, then the range has reverse direction. If direction == false, the starting point is always less than the end point. To make getting the intersection of two ranges easier, for example, I also want to keep a "normalized" start and end for which start < end even if the real start is greater than the end. Since the template parameter E (for element type) can be anything, I don''t want to generate possibly expensive copies of the start and end elements if they are user-defined types. Therefore, I decided to try storing this information in pointers to members. Most of the time this works OK. But for ranges with negative direction, although the elem_ptr members are apparently pointing to the correct members (i.e. reversed), when I dereference them I get the wrong data: e.g. this->*m_pNormalizedStart will return m_start instead of m_end, although the debugger is showing "&Range<int,int>::m_end" for m_pNormalizedStart. I know I can just use a member function to return the normalized data and only need to compare m_start to m_end. That wouldn''t be a problem, also since it could be inlined, but I want to know in general if using pointers to members like this is OK. Is there something "fishy" about how I am setting the member pointers in the constructor? I know that the object isn''t fully constructed yet at member initialization time; however, the member data is initialized first and therefore should have a valid address. I also thought that the compiler might be treating the pointers to memebers like static data (since that is the syntax for setting their value) and overwriting them when a new Range is created with a different direction. However, I assume that each Range object would have a distinct set of pointers to member. Maybe this isn''t a valid assumption? I hope I am just making some other stupid mistake, but I have looked hard and not yet found anything. I don''t think it is a compiler bug because I get the same behavior when running my test code compiled on GCC and Borland. Here is some skeleton code: // declarations: template<typename E, typename D = E> class Range { typedef E Range::*elem_ptr; public: Range<E,D>::Range() : m_start() , m_end() , m_directed(false) , m_pNormalizedStart(&Range::m_start) , m_pNormalizedEnd(&Range::m_end){;} Range<E,D>::Range(const E & startElem , const E & endElem , bool directed) : m_start( directed ? startElem : (startElem > endElem ? endElem : startElem)) , m_end ( directed ? endElem : (startElem < endElem ? endElem : startElem)) , m_directed(directed) , m_pNormalizedStart(m_start <= m_end ? &Range::m_start : &Range::m_end) , m_pNormalizedEnd(m_start <= m_end ? &Range::m_end : &Range::m_start){;} // etc. private: E m_start; E m_end; bool m_directed; elem_ptr m_pNormalizedStart; elem_ptr m_pNormalizedEnd; }; TIA -- Bob Hairgrove No**********@Home

解决方案

On Sat, 03 Jul 2004 16:40:45 +0200, Bob Hairgrove <wo**************@to.know> wrote: oops ... constructors were copied and pasted from a different file. Here''s how they should look:

template<typename E, typename D = E>class Range{ typedef E Range::*elem_ptr;public: Range() : m_start() , m_end() , m_directed(false) , m_pNormalizedStart(&Range::m_start) , m_pNormalizedEnd(&Range::m_end){;} Range(const E & startElem , const E & endElem , bool directed) : m_start( directed ? startElem : (startElem > endElem ? endElem : startElem)) , m_end ( directed ? endElem : (startElem < endElem ? endElem : startElem)) , m_directed(directed) , m_pNormalizedStart(m_start <= m_end ? &Range::m_start : &Range::m_end) , m_pNormalizedEnd(m_start <= m_end ? &Range::m_end : &Range::m_start){;} // etc.private: E m_start; E m_end; bool m_directed; elem_ptr m_pNormalizedStart; elem_ptr m_pNormalizedEnd;};

-- Bob Hairgrove No**********@Home

On Sat, 03 Jul 2004 16:40:45 +0200, Bob Hairgrove <wo**************@to.know> wrote:

The following class contains start and end points of a range of values. The range can have a direction which is implied from the relative order of start and end, or it can be without direction. IOW if start is greater than end, and direction == true, then the range has reverse direction. If direction == false, the starting point is always less than the end point. To make getting the intersection of two ranges easier, for example, I also want to keep a "normalized" start and end for which start < end even if the real start is greater than the end. Since the template parameter E (for element type) can be anything, I don''t want to generate possibly expensive copies of the start and end elements if they are user-defined types. Therefore, I decided to try storing this information in pointers to members. Most of the time this works OK. But for ranges with negative direction, although the elem_ptr members are apparently pointing to the correct members (i.e. reversed), when I dereference them I get the wrong data: e.g. this->*m_pNormalizedStart will return m_start instead of m_end, although the debugger is showing "&Range<int,int>::m_end" for m_pNormalizedStart. I know I can just use a member function to return the normalized data and only need to compare m_start to m_end. That wouldn''t be a problem, also since it could be inlined, but I want to know in general if using pointers to members like this is OK. Is there something "fishy" about how I am setting the member pointers in the constructor? I know that the object isn''t fully constructed yet at member initialization time; however, the member data is initialized first and therefore should have a valid address. I also thought that the compiler might be treating the pointers to memebers like static data (since that is the syntax for setting their value) and overwriting them when a new Range is created with a different direction. However, I assume that each Range object would have a distinct set of pointers to member. Maybe this isn''t a valid assumption? I hope I am just making some other stupid mistake, but I have looked hard and not yet found anything. I don''t think it is a compiler bug because I get the same behavior when running my test code compiled on GCC and Borland. Here is some skeleton code:

Works for me, can''t see anything wrong. #include <iostream> using namespace std; template<typename E, typename D = E> class Range { typedef E Range::*elem_ptr; public: Range() : m_start() , m_end() , m_directed(false) , m_pNormalizedStart(&Range::m_start) , m_pNormalizedEnd(&Range::m_end){;} Range(const E & startElem , const E & endElem , bool directed) : m_start( directed ? startElem : (startElem > endElem ? endElem : startElem)) , m_end ( directed ? endElem : (startElem < endElem ? endElem : startElem)) , m_directed(directed) , m_pNormalizedStart(m_start <= m_end ? &Range::m_start : &Range::m_end) , m_pNormalizedEnd(m_start <= m_end ? &Range::m_end : &Range::m_start){;} // etc. void dump() { cout << this->*m_pNormalizedStart << ''\n''; cout << this->*m_pNormalizedEnd << ''\n''; } private: E m_start; E m_end; bool m_directed; elem_ptr m_pNormalizedStart; elem_ptr m_pNormalizedEnd; }; int main() { Range<int> r(20, 10, true); Range<int> s(10, 20, true); r.dump(); s.dump(); } Output 10 20 10 20 john

On Sat, 03 Jul 2004 16:40:45 +0200, Bob Hairgrove <wo**************@to.know> wrote:

The following class contains start and end points of a range of values. The range can have a direction which is implied from the relative order of start and end, or it can be without direction. IOW if start is greater than end, and direction == true, then the range has reverse direction. If direction == false, the starting point is always less than the end point. To make getting the intersection of two ranges easier, for example, I also want to keep a "normalized" start and end for which start < end even if the real start is greater than the end. Since the template parameter E (for element type) can be anything, I don''t want to generate possibly expensive copies of the start and end elements if they are user-defined types. Therefore, I decided to try storing this information in pointers to members.

You could just use ordinary pointers, or maybe even references. john

更多推荐

指向成员数据问题的指针

本文发布于:2023-07-28 02:45:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1226572.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:指针   成员   数据

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!