class CIndexException : public CException
{
public:
CIndexException (const CIndexException & oSourceObject) :
m_pszMessage(oSourceObject.m_pszMessage) {};
CIndexException & operator = (const CIndexException & oSourceObject)
{
m_pszMessage = oSourceObject.m_pszMessage;
return *this;
};
CIndexException () : CException(), m_pszMessage(0) {};
CIndexException (char * pszError = 0, bool bAutoDelete = true) :
CException(bAutoDelete), m_pszMessage(pszError) {};
const char * GetMessage() { return m_pszMessage; }
protected:
char * m_pszMessage;
};
The build errors I'm getting are as follows:
Error 2 error C2248: 'CObject::CObject' : cannot access private member
declared in class 'CObject' c:\program files\microsoft visual studio
8\vc\atlmfc\include\afx.h 898
Error 4 error C2248: 'CObject::CObject' : cannot access private member
declared in class 'CObject' c:\program files\microsoft visual studio
8\vc\atlmfc\include\afx.h 898
I introduced the copy and assignment constructors thinking they would
remove the errors but they haven't. Would appreciate any help/
suggestions to get this working.
Many thanks in advance.
Also, you should ABSOLUTELY get rid of 'char' as a data type! At the very least, you
should use
LPCTSTR GetMessage() { return m_pszMessage; }
and declare the variable as
LPTSTR m_pszMessage;
although it is seriuosly questionable why you would want a pointer to a string here at
all. And why are you initializing a pointer to 0 when you should initialize it to NULL?
The corrected code should read
CIndexException(LPCTSTR pszError = NULL, bool bAutoDelete = true) :
CException(bAutoDelete), m_pszMessage(pszError)) {}
and declare the string as
CString pszError;
otherwise, you have no idea if the pointer is valid at the point where the GetMessage is
called. CString forces a copy to be made (and don't even THINK of saying anything about
"efficiency"; you are throwing an exception, which is already an expensive operation, and
therefore the cost of constructing a CString is going to be irrelevant...besides, this
only happens when things go wrong!)
And I would actually write GetMessage as
CString GetMessage() { return pszError; }
There is very little justification for using raw character array pointers (and NEVER to
'char', always to TCHAR, that is, LPTSTR or LPCTSTR).
joe
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
> I introduced the copy and assignment constructors thinking they would
> remove the errors but they haven't. Would appreciate any help/
> suggestions to get this working.
As Joe wrote, MFC CException's are different from STL exceptions.
STL exceptions are thrown created on the stack, like
throw std::overflow_error();
Instead CException's must be thrown created on the heap, using 'new' (and
pointers).
Note also that you may want to use DECLARE_DYNAMIC( CYourException ) if you
derive an exception from CException.
You may read 'afx.h' header file for examples of MFC exceptions derived from
CException (or from CSimpleException).
HTH,
Giovanni
>Hello all, I'm having a problem creating a class derived from
>CException in VS2005. Here's the class.:
>
>class CIndexException : public CException
>{
>public:
> CIndexException (const CIndexException & oSourceObject) :
>m_pszMessage(oSourceObject.m_pszMessage) {};
> CIndexException & operator = (const CIndexException & oSourceObject)
> {
> m_pszMessage = oSourceObject.m_pszMessage;
> return *this;
> };
>
> CIndexException () : CException(), m_pszMessage(0) {};
> CIndexException (char * pszError = 0, bool bAutoDelete = true) :
>CException(bAutoDelete), m_pszMessage(pszError) {};
Those are both default constructors, and you can usefully have at most one
in a class. Also, you're not making a copy of the string, which means its
lifetime must exceed that of the exception object, which ain't gonna work
for a non-static local char array. So that's pretty dangerous. Finally, you
should be using const char*.
> const char * GetMessage() { return m_pszMessage; }
>protected:
> char * m_pszMessage;
>};
>
>
>The build errors I'm getting are as follows:
>Error 2 error C2248: 'CObject::CObject' : cannot access private member
>declared in class 'CObject' c:\program files\microsoft visual studio
>8\vc\atlmfc\include\afx.h 898
>Error 4 error C2248: 'CObject::CObject' : cannot access private member
>declared in class 'CObject' c:\program files\microsoft visual studio
>8\vc\atlmfc\include\afx.h 898
>
>
>I introduced the copy and assignment constructors thinking they would
>remove the errors but they haven't. Would appreciate any help/
>suggestions to get this working.
The CObject class is not copyable, and you shouldn't try to make classes
you derive from it copyable. You don't need to, since the CException way is
to throw pointers to CException objects created with new. So get rid of the
copy ctor and assignment operator. For a correct implementation of a class
derived from CException, see MfcGenericException here:
http://members.cox.net/doug_web/eh.htm#Q6
Note the CString member variable to hold the error message (fixes your
lifetime issue) and the function GetErrorMessage, which overrides the
CException virtual function. You can still write your GetMessage function
for your own convenience, but you /must/ override GetErrorMessage so that
when your CIndexException* is caught as a CException*, the error message
will be available. Of course, you should derive your own class from
MfcGenericException along the same lines as MfcStdException.
--
Doug Harrison
Visual C++ MVP