一个简单的类,Release编译模式下的小问题,怀疑和=操作符重载有关!

DDGG 2010-01-14 11:39:30
#include "stdafx.h"
#include "stdlib.h"

//////////////// CCellRange 类 ////////////////

class CCellRange
{
public:

CCellRange(int nMinRow = -1, int nMinCol = -1, int nMaxRow = -1, int nMaxCol = -1)
{
Set(nMinRow, nMinCol, nMaxRow, nMaxCol);
}

void Set(int nMinRow = -1, int nMinCol = -1, int nMaxRow = -1, int nMaxCol = -1);

int GetMinRow() const {return m_nMinRow;}
void SetMinRow(int minRow) {m_nMinRow = minRow;}

int GetMinCol() const {return m_nMinCol;}
void SetMinCol(int minCol) {m_nMinCol = minCol;}

int GetMaxRow() const {return m_nMaxRow;}
void SetMaxRow(int maxRow) {m_nMaxRow = maxRow;}

int GetMaxCol() const {return m_nMaxCol;}
void SetMaxCol(int maxCol) {m_nMaxCol = maxCol;}

int GetRowSpan() const {return m_nMaxRow - m_nMinRow + 1;}
int GetColSpan() const {return m_nMaxCol - m_nMinCol + 1;}

void operator=(const CCellRange& rhs);
int operator==(const CCellRange& rhs);
int operator!=(const CCellRange& rhs);

protected:
int m_nMinRow;
int m_nMinCol;
int m_nMaxRow;
int m_nMaxCol;
};

inline void CCellRange::Set(int minRow, int minCol, int maxRow, int maxCol)
{
m_nMinRow = minRow;
m_nMinCol = minCol;
m_nMaxRow = maxRow;
m_nMaxCol = maxCol;
}

inline void CCellRange::operator=(const CCellRange& rhs)
{
if (this != &rhs) Set(rhs.m_nMinRow, rhs.m_nMinCol, rhs.m_nMaxRow, rhs.m_nMaxCol);
}

inline int CCellRange::operator==(const CCellRange& rhs)
{
return ((m_nMinRow == rhs.m_nMinRow) && (m_nMinCol == rhs.m_nMinCol) &&
(m_nMaxRow == rhs.m_nMaxRow) && (m_nMaxCol == rhs.m_nMaxCol));
}

inline int CCellRange::operator!=(const CCellRange& rhs)
{
return !operator==(rhs);
}

//////////////// GetCellRange 函数 ////////////////

CCellRange GetCellRange()
{
CCellRange result(2, 0, -1, -1);

return result;
}

//////////////// 主函数 ////////////////

int main(int argc, char* argv[])
{
CCellRange cellRange;

cellRange = GetCellRange();

// 正确结果应该输出 2,但却输出 -1 (Debug编译时正常)
printf("%d\n", cellRange.GetMinRow());
system("pause");

return 0;
}



开发环境是VC6,Release编译模式
如果调用时写成 CCellRange cellRange = GetCellRange(); 或者取消CCellRange类中对=操作符的重载也正常。
看了=操作符的代码好像没有问题啊
...全文
210 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
lbjfeng 2010-01-19
  • 打赏
  • 举报
回复
反正不管怎么说,=重载不该返回void吧?
kg307xxb 2010-01-19
  • 打赏
  • 举报
回复
这跟vc6.0编译器优化有关。
函数inline void CCellRange::operator=(const CCellRange& rhs)优化后this == &rhs。

main函数反汇编:
80: int main(int argc, char* argv[])
81: {
00401030 sub esp,10h
82: CCellRange cellRange;
83:
84: cellRange = GetCellRange();
00401033 lea eax,[esp]
00401037 push esi
00401038 push eax
00401039 or esi,0FFh //esi默认值.
0040103C call GetCellRange (00401000)
00401041 lea ecx,[esp+8]
00401045 add esp,4
00401048 cmp ecx,eax //this 与 &rhs比较。
0040104A je main+1Eh (0040104e)
0040104C mov esi,dword ptr [eax] //cellRange.GetMinRow()赋值到esi,this == &rhs不被执行.
85:
86: // 正确结果应该输出 2,但却输出 -1 (Debug编译时正常)
87: printf("%d\n", cellRange.GetMinRow());
0040104E push esi //cellRange.GetMinRow()值.
0040104F push offset string "%d\n" (00408038)
00401054 call _printf (00401106)
DDGG 2010-01-19
  • 打赏
  • 举报
回复
谢谢啊,终于有针对反汇编的解析了,虽然没看懂,但还是结帖了!

to lbjfeng:
重载=操作符是不是应该返回void我也搞不清,这可能是另外一个问题了,不管了!
DDGG 2010-01-14
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 taodm 的回复:]
类的成员函数,要么在类内实现,要么就别加inline,就不该折腾。
[/Quote]

这个CCellRange就是大名鼎鼎的CGridCtrl里的啊,并不是我写的。
这个控件在 http://www.codeproject.com/KB/miscctrl/gridctrl.aspx ,大家应该都用过吧。
taodm 2010-01-14
  • 打赏
  • 举报
回复
类的成员函数,要么在类内实现,要么就别加inline,就不该折腾。
DDGG 2010-01-14
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sunyeyi 的回复:]
vs2008 正常
不好意思,没法帮你看了
[/Quote]

难道这就是传说中的VC6的bug?
arong1234 2010-01-14
  • 打赏
  • 举报
回复
这只是不合乎规范,但是他的代码似乎确实没有大错误
[Quote=引用 12 楼 pengzhixi 的回复:]
inline void CCellRange::operator=(const CCellRange& rhs)
怎么会返回void
[/Quote]
arong1234 2010-01-14
  • 打赏
  • 举报
回复
似乎只要禁止inline就没问题,似乎在这种情况下vc6在处理operator=内的Set时有bug所致
不过vc6已经没有patch了,即使有bug楼主也无可奈何
hlsoven 2010-01-14
  • 打赏
  • 举报
回复
头痛
pengzhixi 2010-01-14
  • 打赏
  • 举报
回复
inline void CCellRange::operator=(const CCellRange& rhs)
怎么会返回void
arong1234 2010-01-14
  • 打赏
  • 举报
回复
确实如此,很奇怪,研究中
DDGG 2010-01-14
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 arong1234 的回复:]
除了你写的测试代码之外,还有其他代码不?即使是不相关的代码也算

[/Quote]

如果有,我就把这帖子打印出来吃下去
taodm 2010-01-14
  • 打赏
  • 举报
回复
珍惜生命,远离VC6.
inline对楼主是祸害。
arong1234 2010-01-14
  • 打赏
  • 举报
回复
不知道有关没关,但是看起来象
楼主看看:
http://blog.vckbase.com/arong/archive/2009/12/30/40598.html
arong1234 2010-01-14
  • 打赏
  • 举报
回复
除了你写的测试代码之外,还有其他代码不?即使是不相关的代码也算
[Quote=引用 6 楼 ddgg 的回复:]
引用 4 楼 arong1234 的回复:
当然你operator=实现也有问题就是,他应该返回一个TYPE&,而不是void
至于你的问题,从给出的代码看,没什么问题,估计你贴的代码不是真实代码



当然是真实的代码,有VC6的同学可以新建一个Win32 Console Application项目,然后在主cpp里贴入顶楼的代码,选Release方式编译后运行。真的输出-1啊,骗你们是小狗
[/Quote]
DDGG 2010-01-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 arong1234 的回复:]
当然你operator=实现也有问题就是,他应该返回一个TYPE&,而不是void
至于你的问题,从给出的代码看,没什么问题,估计你贴的代码不是真实代码

[/Quote]

当然是真实的代码,有VC6的同学可以新建一个Win32 Console Application项目,然后在主cpp里贴入顶楼的代码,选Release方式编译后运行。真的输出-1啊,骗你们是小狗
FrankSun80 2010-01-14
  • 打赏
  • 举报
回复
vs2008 正常
不好意思,没法帮你看了
arong1234 2010-01-14
  • 打赏
  • 举报
回复
当然你operator=实现也有问题就是,他应该返回一个TYPE&,而不是void
至于你的问题,从给出的代码看,没什么问题,估计你贴的代码不是真实代码
hai040 2010-01-14
  • 打赏
  • 举报
回复
写多个拷贝构造函数试试
arong1234 2010-01-14
  • 打赏
  • 举报
回复
CCellRange cellRange = GetCellRange();
这根本不调用operator=,所以和operator =毫无关系
楼主需要看的是拷贝构造函数
[Quote=引用楼主 ddgg 的回复:]
C/C++ code#include"stdafx.h"
#include"stdlib.h"//////////////// CCellRange 类////////////////class CCellRange
{public:

CCellRange(int nMinRow=-1,int nMinCol=-1,int nMaxRow=-1,int nMaxCol=-1)
{
Set(nMinRow, nMinCol, nMaxRow, nMaxCol);
}void Set(int nMinRow=-1,int nMinCol=-1,int nMaxRow=-1,int nMaxCol=-1);int GetMinRow()const {return m_nMinRow;}void SetMinRow(int minRow) {m_nMinRow= minRow;}int GetMinCol()const {return m_nMinCol;}void SetMinCol(int minCol) {m_nMinCol= minCol;}int GetMaxRow()const {return m_nMaxRow;}void SetMaxRow(int maxRow) {m_nMaxRow= maxRow;}int GetMaxCol()const {return m_nMaxCol;}void SetMaxCol(int maxCol) {m_nMaxCol= maxCol;}int GetRowSpan()const {return m_nMaxRow- m_nMinRow+1;}int GetColSpan()const {return m_nMaxCol- m_nMinCol+1;}voidoperator=(const CCellRange& rhs);intoperator==(const CCellRange& rhs);intoperator!=(const CCellRange& rhs);protected:int m_nMinRow;int m_nMinCol;int m_nMaxRow;int m_nMaxCol;
};

inlinevoid CCellRange::Set(int minRow,int minCol,int maxRow,int maxCol)
{
m_nMinRow= minRow;
m_nMinCol= minCol;
m_nMaxRow= maxRow;
m_nMaxCol= maxCol;
}

inlinevoid CCellRange::operator=(const CCellRange& rhs)
{if (this!=&rhs) Set(rhs.m_nMinRow, rhs.m_nMinCol, rhs.m_nMaxRow, rhs.m_nMaxCol);
}

inlineint CCellRange::operator==(const CCellRange& rhs)
{return ((m_nMinRow== rhs.m_nMinRow)&& (m_nMinCol== rhs.m_nMinCol)&&
(m_nMaxRow== rhs.m_nMaxRow)&& (m_nMaxCol== rhs.m_nMaxCol));
}

inlineint CCellRange::operator!=(const CCellRange& rhs)
{return!operator==(rhs);
}//////////////// GetCellRange 函数////////////////
CCellRange GetCellRange()
{
CCellRange result(2,0,-1,-1);return result;
}//////////////// 主函数////////////////int main(int argc,char* argv[])
{
CCellRange cellRange;

cellRange= GetCellRange();// 正确结果应该输出 2,但却输出 -1 (Debug编译时正常) printf("%d\n", cellRange.GetMinRow());
system("pause");return0;
}

开发环境是VC6,Release编译模式。
如果调用时写成 CCellRange cellRange = GetCellRange(); 或者取消CCellRange类中对=操作符的重载也正常。
看了=操作符的代码好像没有问题啊
[/Quote]
加载更多回复(2)

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧