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 의 범주에 든다 . 이 단원의 목적
Une image / un lien ci-dessous est fourni (tel quel) pour télécharger la présentation
Politique de téléchargement : le contenu du site vous est fourni TEL QUEL pour votre information et votre usage personnel ; il ne peut être vendu, concédé sous licence ni partagé sur d’autres sites sans l’accord de son auteur.Le contenu vous est fourni TEL QUEL, pour votre information et votre usage personnel uniquement.Téléchargez la présentation en cliquant sur ce lien.Lors du téléchargement, si vous ne parvenez pas à télécharger une présentation, l’éditeur a peut-être supprimé le fichier de son serveur.Pendant le téléchargement, si vous ne parvenez pas à obtenir une présentation, le fichier a peut-être été supprimé par l’éditeur.
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의 범주에 든다. • 이 단원의 목적 • MFC 개발자 들의 technique • 앞으로의 project에 도움
Simple Value Types • Simple value types • C++ type(char*, …), Windows type(RECT, …) 들을 encapsulating 한 클래스들 • C++ interface 제공 • 더 안전하고 더 쉽게 이용할 수 있는 operator 제공 • memory management • internationalization • …
Class CString • Character string을 encapsulate함 • 다음과 같은 특징이 있음 • Internationalization • Memory allocation/deallocation • Operators(+, =, ==, …) • String searching • String manipulation(reverse, concat) • Formatting(printf-like)
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;
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);
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);
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;
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); } };
CString Internals (cont’d) • 의문점 • CString class는 string 이외의 데이터를 숨김 • 왜, 그들을 멤버변수로 추가하지 않았는가 • CString object와 TCHAR *은 똑같아야 한다. • same bits • 그 이외의 부가적인 정보는 CStringData 에서 관리 • 이전 버전과의 호환성
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
CString Internals (cont’d) • Reference counting 과정 • nRefs 변수의 값이 -1 으로 초기화 • 그 string에 새 참조가 발생하면 1 증가 • 참조가 줄어들면 1 감소 • 다시 0이 되면 삭제 가능 • 참조되는 string에 쓰기가 발생하면 새로운 string을 생성하고 원래의 string의 nRefs값을 1 감소 • Critical resource • 일종의 OS에서 발생하는 resource 공유 문제 • 두 thread 에서 동시에 참조를 증가 혹은 감소시키는 경우 문제 해결 • InterlockedIncrement(), InterlockedDecrement()
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();
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
Class CRect • Declaration (AFXWIN.H) class CRect : public tagRECT { … typedef struct tagRECT { LONG left; LONG top; LONG right; LONG bottom; } RECT;
Class CRect (cont’d) void CRect::DeflateRect(LPCRECT lpRect) { left += lpRect->left; top += lpRect->top; right -= lpRect->right; bottom -= lpRect->bottom; }
MFC Collection Classes • MFC collection classes • Array • 일반적인 C++에서의 array임 • 단 모든 메모리관련 기능 추가 • List • Doubly linked list • Map • 일종의 dictionary • Key, value 쌍으로 데이터를 저장
Type of Collection Classes • Template-based • Nontemplate-based • Array : CObArray, CByteArray, … • List : CObList, CPtrList, CStringList • Map : CMapPtrToWord, …
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(); } };
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(); } };
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); }
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);
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);
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; };
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()를 통한 이해
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; }
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)];
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; } }
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
CWordArray Class (cont’d) • SetAt()(AFXCOLL.INL) • m_pData[nIndex] = newElement; • InsertAt()(ARRAY_W.CPP) • Array마지막에 insert하는 경우 • 메모리 할당 후 insert • Array 중간에 insert하는 경우 • 메모리 할당 후 데이터 이동작업 • Expensive 무분별한 사용을 삼가
Connexion au compte
Connectez-vous pour publier votre contenu sur SlideServe.