想彻底了解运算符重载,其他的如函数重载,继承,多态都已经有所了解!看了一些运算符重载的例子,总觉得不是简化,反而是让代码变得不清 看书上的函数重载例子,基本能看到,但不知道为什么那样做,因为我觉得很繁琐,也容易理解!不明白WHY?还有就是特别想知道运算符重载的实际应用!分不够再加~~希望能举出一些例子,先谢谢了~! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 上文应该是 也不容易理解看书上的函数重载例子,基本能看到,但不知道为什么那样做,因为我觉得很繁琐,也不容易理解!不明白WHY? CString str1 = "123";CString str2 = "456";CString str3 = str1 + str2;str3 = "123456";虽然运算符重载很繁琐,你用者也方便 运算符 + 的代码如下,是不是方便别人使用?CString AFXAPI operator+(const CString& string1, const CString& string2){ CString s; s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, string2.GetData()->nDataLength, string2.m_pchData); return s;} 运算符重载:你可以用,也可以不用(Java好像没用)但确实很有用,比如cout << strMsg;中的"<<".complex类的"+ - * / ..."重载:x + y*z比add(x, (multiply(y, z)))容易理解的多 可不可以说我们应该多使用C++提供给我们的已经写好的运算符重载,比如说字符串类的+,<<,而不需要自己编写运算符重载的类!如果不是,自己写运算符重载有没有很多适当的用处!对了,还有,上文中写的我不明白后面的x+y*z这个也属于运算符重载?我们学C时这都是标准的运算符啊。我看的讲运算符重载的例子也举了这种例子,不明白! 有时需要我们自己重载运算符的比如,你定义了一个自己的结构体,你希望能实现结构体的相加,这是就需要重载运算符operator+ 好象有那么一点理解了!!只是还不知道能在哪方面马上用到他~除了+和<<这些,偶指自己写得 存在就有它的道理.这个例子是很难说得明白,现在俺在做一个程序,为了简化代码和增加可读性,不得不用重载运算符,到要你的时候,你自然知道为什么,HEHE 给一个多继承的重载sample.CEventObject& CEventObject::operator = (CEventObject& other){ CThing * pThing1 = dynamic_cast<CThing *>(this); CThing * pThing2 = dynamic_cast<CThing *>(&other); ASSERT(pThing1); ASSERT(pThing2); *pThing1 = *pThing2; CNodeTracker * pNode1 = dynamic_cast<CNodeTracker *>(this); CNodeTracker * pNode2 = dynamic_cast<CNodeTracker *>(&other); ASSERT(pNode1); ASSERT(pNode2); *pNode1 = *pNode2; m_eventtype = other.m_eventtype; InitParent();// m_pParentObject = other.m_pParentObject;不能有这句,是个陷阱 return * this;} 说实话,看不懂;(CEventObject& CEventObject::operator = (CEventObject& other) //这是声明一个返回CEventObject类的引用的重载=号的函数,参数是CEventObject类的引用??//是这样吗?以下得就看不懂了,很多关键字都没有,书上也没有!:(唉~ dynamic_cast<CThing *>(this);dynamic_cast是否是一个宏?尖括号是什么意思呢?在宏里定义的?还有ASSERT(pThing1)里的pThing会是什么值呢?NULL即是假?其他为真?m_pParentObject = other.m_pParentObject;为什么不能有这句呢? dynamic_cast 是c++中建议使用的强制类型转换关键字,CNodeTracker *pNode1 = dynamic_cast<CNodeTracker*>(this);相当于CNodeTracker *pNode1 = (CNodeTracker*)(this);看起来挺难看的,用C++之父的话说就是为了让你用着时感到难受从而减少使用类型强制转换,因为有时类型强制转换会带来意想不到的错误楼主应该先看看新的C++基础教程,对c++语法先有个了解 wwwllg(wwwllg)兄也不把例子写全了,不知那个m_pParentObject是个什么东西InitParent ? 如果CEventObject是另一个类的成员,用于存储事件,难道InitParent能替一个事件(CEventObject)产生一个父?(CParentObject??) 呵呵,你看的书太老了,C++ 94,95年时就做了大扩展,主要增加了模板,引入了范型编程的概念,顺带增加了些类型转换和其他一些关键字,我说的不是书名,但这类书很多,google上搜搜吧 不好意思,引入我以前的部分源码,确给大家造成了误会。dynamic_cast 是很有用的,他不是强制转换。具体的可以看msdn,讲的很详细。class CThing //这是其中一个基类 {public: HTREEITEM InitTree(CTreeCtrl &_tree,HTREEITEM _hti); CThing(); virtual ~CThing();public: virtual void LoadMenuItems(CMenu *_pMenu); virtual BOOL CanChangeProperty(); virtual void Property(); void ClearThings(); CThing& operator = (CThing& other); virtual void Copy(CThing* _pThing); virtual CThing* AllocalNode();//必须实现 virtual BOOL IsHaveNode(CThing *_pThing); virtual void AddNode(CThing *_pThing); virtual void DeleteNode(CThing *_pThing); virtual void PopMenu( CPoint point); THINGTYPE m_thingtype;//事类型 string m_commen;//备注 string m_title;//外在的名字 SYSTEMTIME m_timeCreate;//创建时间 SYSTEMTIME m_timeLastModi;//修改时间 list<CThing*> m_things;};#include "DpLpChange.h"class CRectTracker;class CMapView;class CNodeTracker : public CRectTracker {public: enum NODETYPE { NODEBASE = 0, POLICE, LABLE, POLICE_FJ, POLICE_OFFICE }m_nodeType;public: CNodeTracker(); virtual ~CNodeTracker();public: virtual BOOL LbClk(); virtual void DbClk(); virtual void CopyData(CNodeTracker *_pNode); virtual void DrawFouceEllipse(CDC *pDC,CRect _rect,COLORREF crFocus = RGB(255,0,0)); virtual void Serialize(CArchive& ar); virtual void DrawSmall(CDC* pDC,CRect rect) ; virtual void Draw(CDC* pDC) ; virtual CString GetToolTipText(); virtual BOOL PropertyDlg(BOOL bCanChanged = false);public: virtual void ReDraw(); COLORREF GetClrBorder(); COLORREF GetClrFore(); COLORREF GetClrBk(); COLORREF GetClrSmall(); void SetClrBorder(COLORREF clBorder); void SetClrFore(COLORREF clFore); void SetClrBk(COLORREF clBk); void SetClrSmall(COLORREF clSmall); BOOL IsSelected(); BOOL Track(CWnd* pWnd, CPoint point); BOOL SetCursor(CWnd* pWnd, UINT nHitTest) ; void Selected(BOOL _bSelected = true); void EnableMove(BOOL bMove = true); void EnableChangeSize(BOOL bEnable = true); void SetPosition(CPoint _point); void SetPosition(CRect _rect); void SetSize(int cx,int cy); void SetSize(CSize _size); void SetTrackerView(CWnd * _pView); void GetInvaliteRect(CRect &_invaliteRect); CSize GetSize(); CNodeTracker &operator = (CNodeTracker&other);protected: virtual void DrawTrackerRect(LPCRECT lpRect, CWnd* pWndClipTo, CDC* pDC, CWnd* pWnd); virtual void OnChangedRect(const CRect& rectOld); BOOL TrackHandle(int nHandle, CWnd* pWnd, CPoint point, CWnd* pWndClipTo);protected: CMapView * m_pView; CSize m_size; BOOL m_bEnableChangeSize; BOOL m_bEnableMove; BOOL m_bSelected; BOOL m_bMoved; COLORREF m_crBk; COLORREF m_crFore; COLORREF m_crSmall; COLORREF m_crBorder; };class CEventObject : public CThing,public CNodeTracker;{....}m_pParentObject = other.m_pParentObject;中的m_pParentObject是为指向父类的指针,我在实现对象的cpy的时候,用的,因为,指针是不能cpy的,这样,相当于,类之间的关系发生错误。 如果在多继承中把指针强制转换,那么在很多情况,并不能产生正确的结果,因为,this指针,已经发生变化。它不能指向正确的对象指针,除非你知道当前的一个32位的值是一个明确的类对象(你知道就是它),否则,会产生不可预料的结果。而用dynamic_cast 可以避免这种情况,在不是指向你期望的对象时,返回NULL。 运算符重载,本身就是个“语法糖”,至于会不会简化你的使用,要看用在什么场合,怎么重载了。比如CString的+运算符就很好,你可以方便地连接两个字符串。但是,如果你重载CString的-运算符来作字符串连接,那只能让你的程序更难懂!要注意,你在写运算符重载时,可能很累,代码比较麻烦,但是,请记住,一个类可能只写一次,但会被使用N次,所以与其每次用到时都重写一遍代码,还不如在写这个类的时候就把运算符重载了!!! 有没有关于ArcGIS和VC开发结合的书籍 关于保存wav文件的问题 关于用ShellExecute打印word的问题,很烦人 VC中如何模拟键盘输入Ctrl+Alt+Del来切换至Winlogon桌面??? 100分网络编程高手寻求一个思路 关于PHOTOSHOP下旋转后对锯齿的处理方式(100分) VC中插入类时,生成头文件的问题 我是一个初学者,我想知道如何在VC中调用IE打开一个网页文件 请给位高手帮忙 关于串口问题 很简单的vc入门问题!绝对给分!!!! 不解:在java里,生成一个javaBean就可以马上使用,但在com里却要注册? 请问哪里有vc下载?
看书上的函数重载例子,基本能看到,但不知道为什么那样做,因为我觉得很繁琐,也不容易理解!不明白WHY?
CString str2 = "456";
CString str3 = str1 + str2;
str3 = "123456";
虽然运算符重载很繁琐,你用者也方便
CString AFXAPI operator+(const CString& string1, const CString& string2)
{
CString s;
s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData,
string2.GetData()->nDataLength, string2.m_pchData);
return s;
}
complex类的"+ - * / ..."重载:
x + y*z比add(x, (multiply(y, z)))容易理解的多
如果不是,自己写运算符重载有没有很多适当的用处!
对了,还有,上文中写的我不明白后面的x+y*z这个也属于运算符重载?我们学C时这都是标准的运算符啊。我看的讲运算符重载的例子也举了这种例子,不明白!
比如,你定义了一个自己的结构体,你希望能实现结构体的相加,这是就需要重载运算符
operator+
这个例子是很难说得明白,现在俺在做一个程序,为了简化代码和增加可读性,不得不用重载运算符,到要你的时候,你自然知道为什么,
HEHE
CEventObject& CEventObject::operator = (CEventObject& other)
{
CThing * pThing1 = dynamic_cast<CThing *>(this);
CThing * pThing2 = dynamic_cast<CThing *>(&other);
ASSERT(pThing1);
ASSERT(pThing2);
*pThing1 = *pThing2;
CNodeTracker * pNode1 = dynamic_cast<CNodeTracker *>(this);
CNodeTracker * pNode2 = dynamic_cast<CNodeTracker *>(&other);
ASSERT(pNode1);
ASSERT(pNode2);
*pNode1 = *pNode2;
m_eventtype = other.m_eventtype;
InitParent();
// m_pParentObject = other.m_pParentObject;不能有这句,是个陷阱 return * this;
}
CEventObject& CEventObject::operator = (CEventObject& other) //这是声明一个返回CEventObject类的引用的重载=号的函数,参数是CEventObject类的引用??//是这样吗?
以下得就看不懂了,很多关键字都没有,书上也没有!:(唉~
dynamic_cast是否是一个宏?尖括号是什么意思呢?在宏里定义的?
还有ASSERT(pThing1)里的pThing会是什么值呢?NULL即是假?其他为真?m_pParentObject = other.m_pParentObject;为什么不能有这句呢?
CNodeTracker *pNode1 = dynamic_cast<CNodeTracker*>(this);
相当于CNodeTracker *pNode1 = (CNodeTracker*)(this);
看起来挺难看的,用C++之父的话说就是为了让你用着时感到难受
从而减少使用类型强制转换,因为有时类型强制转换会带来意想不到的错误楼主应该先看看新的C++基础教程,对c++语法先有个了解
不知那个m_pParentObject是个什么东西
InitParent ? 如果CEventObject是另一个类的成员,用于存储事件,难道InitParent
能替一个事件(CEventObject)产生一个父?(CParentObject??)
引入了范型编程的概念,顺带增加了些类型转换和其他一些关键字,
我说的不是书名,但这类书很多,google上搜搜吧
具体的可以看msdn,讲的很详细。
class CThing //这是其中一个基类
{
public:
HTREEITEM InitTree(CTreeCtrl &_tree,HTREEITEM _hti);
CThing();
virtual ~CThing();
public:
virtual void LoadMenuItems(CMenu *_pMenu);
virtual BOOL CanChangeProperty();
virtual void Property();
void ClearThings();
CThing& operator = (CThing& other);
virtual void Copy(CThing* _pThing);
virtual CThing* AllocalNode();//必须实现
virtual BOOL IsHaveNode(CThing *_pThing);
virtual void AddNode(CThing *_pThing);
virtual void DeleteNode(CThing *_pThing);
virtual void PopMenu( CPoint point);
THINGTYPE m_thingtype;//事类型
string m_commen;//备注
string m_title;//外在的名字
SYSTEMTIME m_timeCreate;//创建时间
SYSTEMTIME m_timeLastModi;//修改时间
list<CThing*> m_things;
};#include "DpLpChange.h"
class CRectTracker;
class CMapView;
class CNodeTracker : public CRectTracker
{public:
enum NODETYPE
{
NODEBASE = 0,
POLICE,
LABLE,
POLICE_FJ,
POLICE_OFFICE
}m_nodeType;
public:
CNodeTracker();
virtual ~CNodeTracker();
public:
virtual BOOL LbClk();
virtual void DbClk();
virtual void CopyData(CNodeTracker *_pNode);
virtual void DrawFouceEllipse(CDC *pDC,CRect _rect,COLORREF crFocus = RGB(255,0,0));
virtual void Serialize(CArchive& ar);
virtual void DrawSmall(CDC* pDC,CRect rect) ;
virtual void Draw(CDC* pDC) ;
virtual CString GetToolTipText();
virtual BOOL PropertyDlg(BOOL bCanChanged = false);public:
virtual void ReDraw();
COLORREF GetClrBorder();
COLORREF GetClrFore();
COLORREF GetClrBk();
COLORREF GetClrSmall();
void SetClrBorder(COLORREF clBorder);
void SetClrFore(COLORREF clFore);
void SetClrBk(COLORREF clBk);
void SetClrSmall(COLORREF clSmall);
BOOL IsSelected();
BOOL Track(CWnd* pWnd, CPoint point);
BOOL SetCursor(CWnd* pWnd, UINT nHitTest) ;
void Selected(BOOL _bSelected = true);
void EnableMove(BOOL bMove = true);
void EnableChangeSize(BOOL bEnable = true);
void SetPosition(CPoint _point);
void SetPosition(CRect _rect);
void SetSize(int cx,int cy);
void SetSize(CSize _size);
void SetTrackerView(CWnd * _pView);
void GetInvaliteRect(CRect &_invaliteRect);
CSize GetSize();
CNodeTracker &operator = (CNodeTracker&other);
protected:
virtual void DrawTrackerRect(LPCRECT lpRect, CWnd* pWndClipTo,
CDC* pDC, CWnd* pWnd);
virtual void OnChangedRect(const CRect& rectOld);
BOOL TrackHandle(int nHandle, CWnd* pWnd, CPoint point, CWnd* pWndClipTo);protected:
CMapView * m_pView;
CSize m_size;
BOOL m_bEnableChangeSize;
BOOL m_bEnableMove;
BOOL m_bSelected;
BOOL m_bMoved;
COLORREF m_crBk;
COLORREF m_crFore;
COLORREF m_crSmall;
COLORREF m_crBorder;
};class CEventObject : public CThing,public CNodeTracker;
{....
}m_pParentObject = other.m_pParentObject;中的m_pParentObject是为指向父类的指针,
我在实现对象的cpy的时候,用的,因为,指针是不能cpy的,这样,相当于,类之间的关系发生错误。
但是,如果你重载CString的-运算符来作字符串连接,那只能让你的程序更难懂!要注意,你在写运算符重载时,可能很累,代码比较麻烦,但是,请记住,一个类可能只写一次,但会被使用N次,所以与其每次用到时都重写一遍代码,还不如在写这个类的时候就把运算符重载了!!!