slide1 n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Chapter 04 MFC Utility Class PowerPoint Presentation
Download Presentation
Chapter 04 MFC Utility Class

Loading in 2 Seconds...

play fullscreen
1 / 162

Chapter 04 MFC Utility Class - PowerPoint PPT Presentation


  • 289 Views
  • Uploaded on

Chapter 04 MFC Utility Class. Contents. Simple value types 일반적 목적 : CString, CTime, CTimeSpan 윈도우 구조체 : CPoint, CSize, Crect MFC collection classes array, linked list, map CFile class family CException class. Introduction. 우리가 만드는 많은 class 들 Utility class 의 범주에 든다 . 이 단원의 목적

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

Chapter 04 MFC Utility Class


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
    Presentation Transcript
    1. Chapter04 MFC Utility Class

    2. Contents • Simple value types • 일반적 목적 : CString, CTime, CTimeSpan • 윈도우 구조체 : CPoint, CSize, Crect • MFC collection classes • array, linked list, map • CFile class family • CException class

    3. Introduction • 우리가 만드는 많은 class들 • Utility class의 범주에 든다. • 이 단원의 목적 • MFC 개발자 들의 technique • 앞으로의 project에 도움

    4. Simple Value Types • Simple value types • C++ type(char*, …), Windows type(RECT, …) 들을 encapsulating 한 클래스들 • C++ interface 제공 • 더 안전하고 더 쉽게 이용할 수 있는 operator 제공 • memory management • internationalization • …

    5. Class CString • Character string을 encapsulate함 • 다음과 같은 특징이 있음 • Internationalization • Memory allocation/deallocation • Operators(+, =, ==, …) • String searching • String manipulation(reverse, concat) • Formatting(printf-like)

    6. Using a CString • 생성 // create a CString from a char * CString myString1(“This is a string”); // create a CString from a CString CString myString2(myString1); // create a CString with 80 z characters CString myString3(‘z’, 80); // create a CString as empty CString CString myString4;

    7. Using a CString (cont’d) CString myString1(“string 1”); CString myString2(“string 2”); CString myString3(“string 3”); // addition (concatenation) & assignment myString1 += myStrig2; myString3 = “This is “ + myString2; myString2 += ‘Z’; // comparison : == , < , != , … if ( myString1 == myString2 ) // like strcmp // operator[] : 0-based if ( myString1[7] == ‘l’ ) // find : Find(), FindOneOf(), ReverseFind()

    8. CString Internals • CString declaration(AFX.H) classCString { public: //Constructors CString(); CString(const CString& stringSrc); CString(TCHAR ch, int nRepeat = 1); CString(LPCSTR lpsz); CString(LPCWSTR lpsz); CString(LPCSTR lpch, int nLength); CString(LPCWSTR lpch, int nLength); CString(const unsigned char* psz);

    9. CString Internals (cont’d) // Attributes & Operations int GetLength() const; BOOL IsEmpty() const; void Empty(); TCHAR GetAt(int nIndex) const; TCHAR operator[](int nIndex) const; void SetAt(int nIndex, TCHAR ch); operator LPCTSTR() const; const CString& operator=(const CString& stringSrc); const CString& operator=(TCHAR ch); const CString& operator=(LPCSTR lpsz); const CString& operator=(LPCWSTR lpsz); const CString& operator=(const unsigned char* psz);

    10. CString Internals (cont’d) // concatenate const CString& operator+=(const CString& string); const CString& operator+=(TCHAR ch); const CString& operator+=(LPCTSTR lpsz); friend CString AFXAPI operator+(const CString& string1, const CString& string2); friend CString AFXAPI operator+(const CString& string, TCHAR ch); friend CString AFXAPI operator+(TCHAR ch, const CString& string); friend CString AFXAPI operator+(const CString& string, LPCTSTR lpsz); friend CString AFXAPI operator+(LPCTSTR lpsz, const CString& string); // string comparison int Compare(LPCTSTR lpsz) const; int CompareNoCase(LPCTSTR lpsz) const; int Collate(LPCTSTR lpsz) const; int CollateNoCase(LPCTSTR lpsz) const;

    11. CString Internals (cont’d) // simple sub-string extraction CString Mid(int nFirst, int nCount) const; CString Mid(int nFirst) const; CString Left(int nCount) const; CString Right(int nCount) const; CString SpanIncluding(LPCTSTR lpszCharSet) const; CString SpanExcluding(LPCTSTR lpszCharSet) const; // upper/lower/reverse conversion void MakeUpper(); void MakeLower(); void MakeReverse(); // advanced manipulation int Replace(TCHAR chOld, TCHAR chNew); int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew); int Remove(TCHAR chRemove); int Insert(int nIndex, TCHAR ch); int Insert(int nIndex, LPCTSTR pstr); int Delete(int nIndex, int nCount = 1);

    12. CString Internals (cont’d) // searching int Find(TCHAR ch) const; int ReverseFind(TCHAR ch) const; int Find(TCHAR ch, int nStart) const; int FindOneOf(LPCTSTR lpszCharSet) const; int Find(LPCTSTR lpszSub) const; int Find(LPCTSTR lpszSub, int nStart) const; // simple formatting void AFX_CDECL Format(LPCTSTR lpszFormat, ...); void AFX_CDECL Format(UINT nFormatID, ...); void FormatV(LPCTSTR lpszFormat, va_list argList); // input and output friend CArchive& AFXAPI operator<<(CArchive& ar, const CString& string); friend CArchive& AFXAPI operator>>(CArchive& ar, CString& string); // load from string resource BOOL LoadString(UINT nID);

    13. CString Internals (cont’d) // get pointer to modifiable buffer at least as long as nMinBufLength LPTSTR GetBuffer(int nMinBufLength); // release buffer, setting length to nNewLength (or to first nul if -1) void ReleaseBuffer(int nNewLength = -1); // get pointer to modifiable buffer exactly as long as nNewLength LPTSTR GetBufferSetLength(int nNewLength); // release memory allocated to but unused by string void FreeExtra(); // turn refcounting back on LPTSTR LockBuffer(); // turn refcounting off void UnlockBuffer(); // Implementation public: ~CString(); int GetAllocLength() const;

    14. CString Internals (cont’d) protected: LPTSTR m_pchData; // pointer to ref counted string data // implementation helpers CStringData* GetData() const; void Init(); void AllocCopy(CString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const; void AllocBuffer(int nLen); void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData); void ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data, int nSrc2Len, LPCTSTR lpszSrc2Data); void ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData); void CopyBeforeWrite(); void AllocBeforeWrite(int nLen); static void PASCAL Release(CStringData* pData); static int PASCAL SafeStrlen(LPCTSTR lpsz); static void FASTCALL FreeData(CStringData* pData); };

    15. CString Internals (cont’d) • CString declaration(AFX.H) • m_pchData • 유일한 멤버 변수 • String에 대한 pointer • CStringData • CString의 기능 구현을 도와주는 structure structCStringData { long nRefs; // reference count int nDataLength; // length of data (including terminator) int nAllocLength; // length of allocation TCHAR* data() // TCHAR* to managed data { return (TCHAR*)(this+1); } };

    16. CString Internals (cont’d) • 공간 할당 함수 AllocBuffer()(STRCORE.CPP) void CString::AllocBuffer(int nLen) { if (nLen == 0) Init(); else { CStringData*pData = (CStringData*)newBYTE[sizeof(CStringData) + (nLen+1)*sizeof(TCHAR)]; pData->nAllocLength = nLen; pData->nRefs = 1; pData->data()[nLen] = '\0'; pData->nDataLength = nLen; m_pchData= pData->data(); } }

    17. CStringData Data(nlength + 1) nRefs nDataLength nAllocLength CString::m_pchData CString Internals (cont’d) • AllocBuffer()함수에 의한 memory 할당

    18. CString Internals (cont’d) • 의문점 • CString class는 string 이외의 데이터를 숨김 • 왜, 그들을 멤버변수로 추가하지 않았는가 • CString object와 TCHAR *은 똑같아야 한다. • same bits • 그 이외의 부가적인 정보는 CStringData 에서 관리 • 이전 버전과의 호환성

    19. CString Internals (cont’d) • Reference counting • CStringData::nRefs • 실제 데이터의 변경이 가해지면 copy CString myString1(“This is a string”); CString myString2(myString1); CString myString3 = myString1; myString2 myString1 “This is a string” myString3

    20. CString Internals (cont’d) • Reference counting 과정 • nRefs 변수의 값이 -1 으로 초기화 • 그 string에 새 참조가 발생하면 1 증가 • 참조가 줄어들면 1 감소 • 다시 0이 되면 삭제 가능 • 참조되는 string에 쓰기가 발생하면 새로운 string을 생성하고 원래의 string의 nRefs값을 1 감소 • Critical resource • 일종의 OS에서 발생하는 resource 공유 문제 • 두 thread 에서 동시에 참조를 증가 혹은 감소시키는 경우 문제 해결 • InterlockedIncrement(), InterlockedDecrement()

    21. CString Internals (cont’d) • 예제 Line 1 Line 2 Line 3 Line 4 Line 5 CString myString1(“This is my string1”); CString myString2(myString1); CString myString3; myString3 = myString2; // Write somthing myString3.MakeUpper();

    22. CString Internals (cont’d) “Strcore.cpp” CString::CString(LPCTSTR lpsz) { int nLen = SafeStrlen(lpsz); if (nLen != 0) { AllocBuffer(nLen); memcpy(m_pchData, lpsz, nLen*sizeof(TCHAR)); } } myString1 “This is my string1” 1

    23. CString Internals (cont’d) CString::CString(const CString& stringSrc) { if (stringSrc.GetData()->nRefs >= 0) { m_pchData = stringSrc.m_pchData; InterlockedIncrement(&GetData()->nRefs); } else { Init(); *this = stringSrc.m_pchData; } } myString1 “This is my string1” 2 myString2

    24. CString Internals (cont’d) const CString& CString::operator=(const CString& stringSrc) { if (m_pchData != stringSrc.m_pchData) { if ((GetData()->nRefs < 0 && GetData() != _afxDataNil) || stringSrc.GetData()->nRefs < 0) { // actual copy necessary since one of the strings is locked AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData); } else { // can just copy references around Release(); m_pchData = stringSrc.m_pchData; InterlockedIncrement(&GetData()->nRefs); } } return *this; } myString2 myString1 “This is my string1” 3 myString3

    25. CString Internals (cont’d) void CString::MakeUpper() { CopyBeforeWrite(); _tcsupr(m_pchData); } void CString::CopyBeforeWrite() { if (GetData()->nRefs > 1) { CStringData* pData = GetData(); Release(); AllocBuffer(pData->nDataLength); memcpy(m_pchData,pData->data(), (pData->nDataLength+1)*sizeof (TCHAR)); } ASSERT(GetData()->nRefs <= 1); }

    26. CString Internals (cont’d) void CString::Release() { if (GetData() != _afxDataNil) { ASSERT(GetData()->nRefs != 0); if (InterlockedDecrement(&GetData()->nRefs) <= 0) FreeData(GetData()); Init(); } } myString1 “This is my string1” 2 myString2 myString3 “THIS IS MY STRING1” 1

    27. CString Internals (cont’d) • Internationalization • _t internationalized string 함수를 이용하여 구현 • _tcschr() => strchr() mapping int CString::Find(TCHAR ch, int nStart) const { int nLength = GetData()->nDataLength; if (nStart >= nLength) return -1; LPTSTR lpsz =_tcschr(m_pchData + nStart, (_TUCHAR)ch); return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData); }

    28. Other Simple Value Types

    29. Class CRect • Declaration (AFXWIN.H) class CRect : public tagRECT { … typedef struct tagRECT { LONG left; LONG top; LONG right; LONG bottom; } RECT;

    30. Class CRect (cont’d) void CRect::DeflateRect(LPCRECT lpRect) { left += lpRect->left; top += lpRect->top; right -= lpRect->right; bottom -= lpRect->bottom; }

    31. MFC Collection Classes • MFC collection classes • Array • 일반적인 C++에서의 array임 • 단 모든 메모리관련 기능 추가 • List • Doubly linked list • Map • 일종의 dictionary • Key, value 쌍으로 데이터를 저장

    32. Type of Collection Classes • Template-based • Nontemplate-based • Array : CObArray, CByteArray, … • List : CObList, CPtrList, CStringList • Map : CMapPtrToWord, …

    33. Shape Features

    34. Type-safe Collection • Template-based classes • 변수 선언 • 멤버 함수 호출 • 필요할 경우, helper function 구현 (CArray, CList, CMap 에서) • CompareElements • CopyElements • Dumpelements • HashKey • SerializeElements

    35. Type-safe Collection (cont’d) // 변수 선언 CList<int, int> m_intList; // 함수 호출 m_intList.AddTail( 100 ); m_intList.RemoveAll( ); // helper function 구현 class CPerson : public CObject { . . . }; CArray< CPerson, CPerson& > personArray; template <> void AFXAPISerializeElements<CPerson> ( CArchive& ar, CPerson* pNewPersons, int nCount ) { for ( int i = 0; i < nCount; i++, pNewPersons++ ) { // Serialize each CPerson object pNewPersons->Serialize( ar ); } }

    36. Type-safe Collection (cont’d) • Nontemplate-based classes • 방법 1 : Type-casting 활용 • 방법 2 : 파생클래스 생성 class CPerson : public CObject {...}; CPerson* p1 = new CPerson(...); CObList myList; myList.AddHead( p1 ); // No cast needed CPerson* p2 = ( CPerson* )myList.GetHead(); class CPersonList : public CObList { public: voidAddHeadPerson( CPerson* person ) {AddHead( person );} const CPerson*GetHeadPerson() {return (CPerson*)GetHead();} };

    37. Iteration • Array • List CTypedPtrArray<CObArray, CPerson*> myArray; for( int i = 0; i < myArray.GetSize();i++ ){ CPerson* thePerson = myArray.GetAt( i ); // CPerson* thePerson = myArray[ i ]; } CTypedPtrList<CObList, CPerson*> myList; POSITION pos = myList.GetHeadPosition(); while( pos != NULL ) { CPerson* thePerson = myList.GetNext( pos ); ... }

    38. Iteration (cont’d) • Map CMap<CString, LPCTSTR, CPerson*, CPerson*> myMap; POSITION pos = myMap.GetStartPosition(); while( pos != NULL ) { CPerson* pPerson; CString string; myMap.GetNextAssoc( pos, string, pPerson ); } CMapStringToOb myMap; // A nontemplate collection class POSITION pos = myMap.GetStartPosition( ); while( pos != NULL ) { CPerson* pPerson; CString string; myMap.GetNextAssoc( pos, string,(CObject*&)pPerson ); ASSERT( pPerson->IsKindOf( RUNTIME_CLASS( CPerson ) ) ); }

    39. Additional Structures • Stack class CTray : public CObject { ... }; classCStack: public CTypedPtrList< CObList, CTray* > { public: // Add element to top of stack voidPush( CTray* newTray ) { AddHead( newTray ); } // Peek at top element of stack CTray*Peek() { return IsEmpty() ? NULL : GetHead(); } // Pop top element off stack CTray*Pop() { return RemoveHead(); } };

    40. Additional Structures (cont’d) • Queue class CPerson : public CObject { ... }; classCQueue: public CTypedPtrList< CObList, CPerson* > { public: // Go to the end of the line voidAddToEnd( CPerson* newPerson ) { AddTail( newPerson ); } // End of the queue // Get first element in line CPerson*GetFromFront() { return IsEmpty() ? NULL : RemoveHead(); } };

    41. Array Collections • Array collections • CByteArray, CDWordArray, CUintArray • CObArray, CStringArray, CWordArray • AFXCOLL.H • ARRAY_X.CPP ( X : type of array ) void ArrayExample() { CUintArray myIntArray; myIntArray.SetSize(100); for ( int I=0; I<100; I++ ) myIntArray.SetAt(I, 2*I); UINT bogus = myIntArray[50]; bogus = myIntArray.GetAt(50); myIntArray.DeleteAt(50); }

    42. CWordArray Class classCWordArray: public CObject { DECLARE_SERIAL(CWordArray) public: // Attributes int GetSize() const; int GetUpperBound() const; voidSetSize(int nNewSize, int nGrowBy = -1); // Operations void FreeExtra(); void RemoveAll(); WORD GetAt(int nIndex) const; void SetAt(int nIndex, WORD newElement); WORD& ElementAt(int nIndex);

    43. CWordArray Class (cont’d) // Direct Access to the element data (may return NULL) const WORD* GetData() const; WORD* GetData(); // Potentially growing the array void SetAtGrow(int nIndex, WORD newElement); int Add(WORD newElement); int Append(const CWordArray& src); void Copy(const CWordArray& src); // overloaded operator helpers WORD operator[](int nIndex) const; WORD& operator[](int nIndex); // Operations that move elements around void InsertAt(int nIndex, WORD newElement, int nCount = 1); void RemoveAt(int nIndex, int nCount = 1); void InsertAt(int nStartIndex, CWordArray* pNewArray);

    44. CWordArray Class (cont’d) // Implementation protected: WORD* m_pData; // the actual array of data int m_nSize; // # of elements (upperBound - 1) int m_nMaxSize; // max allocated int m_nGrowBy; // grow amount public: ~CWordArray(); void Serialize(CArchive&); #ifdef _DEBUG void Dump(CDumpContext&) const; void AssertValid() const; #endif protected: // local typedefs for class templates typedef WORD BASE_TYPE; typedef WORD BASE_ARG_TYPE; };

    45. CWordArray Class (cont’d) • CWordArray(ARRAY_W.CPP) • 멤버 변수 • m_pData • 저장된 데이터의 포인터 • m_nSize • Current size of array(“logical” size) • m_nMaxSize • “Physical” size • M_nGrowBy • 추가 메모리 할당시 추가 할당 크기 • SetSize()를 통한 이해

    46. CWordArray Class (cont’d) void CWordArray::SetSize(int nNewSize, int nGrowBy) { if (nGrowBy != -1) m_nGrowBy = nGrowBy; // set new size if (nNewSize == 0) { // shrink to nothing delete[] (BYTE*)m_pData; m_pData = NULL; m_nSize = m_nMaxSize = 0; } else if (m_pData == NULL) { // create one with exact size m_pData = (WORD*) new BYTE[nNewSize * sizeof(WORD)]; memset(m_pData, 0, nNewSize * sizeof(WORD)); // zero fill m_nSize = m_nMaxSize = nNewSize; }

    47. CWordArray Class (cont’d) else if (nNewSize <= m_nMaxSize) { // it fits if (nNewSize > m_nSize) { // initialize the new elements memset(&m_pData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(WORD)); } m_nSize = nNewSize; } else { // otherwise, grow array int nGrowBy = m_nGrowBy; if (nGrowBy == 0) nGrowBy = min(1024, max(4, m_nSize / 8)); int nNewMax; if (nNewSize < m_nMaxSize + nGrowBy) nNewMax = m_nMaxSize + nGrowBy; // granularity else nNewMax = nNewSize; // no slush WORD* pNewData = (WORD*) new BYTE[nNewMax * sizeof(WORD)];

    48. CWordArray Class (cont’d) // copy new data from old memcpy(pNewData, m_pData, m_nSize * sizeof(WORD)); memset(&pNewData[m_nSize], 0, (nNewSize-m_nSize)*sizeof(WORD)); // get rid of old stuff (note: no destructors called) delete[] (BYTE*)m_pData; m_pData = pNewData; m_nSize = nNewSize; m_nMaxSize = nNewMax; } }

    49. CWordArray Class (cont’d) • SetSize()(ARRAY_W.CPP) • 5개의 section으로 구성 • Initialization section • Shrink-to-nothing section • First allocation section • Allocate-from-extra-space section • Grow-the-array section

    50. CWordArray Class (cont’d) • SetAt()(AFXCOLL.INL) • m_pData[nIndex] = newElement; • InsertAt()(ARRAY_W.CPP) • Array마지막에 insert하는 경우 • 메모리 할당 후 insert • Array 중간에 insert하는 경우 • 메모리 할당 후 데이터 이동작업 • Expensive  무분별한 사용을 삼가