|
piul wrote: On the other hand, I'd considered using dynamic casting, but the book I'm reading says it is not recommendable. That it might be a sign of poor inheritance hierarchy design.
It might be a sign. It is not for fact a poor or bad design.
codito ergo sum
|
|
|
|
|
piul wrote: On the other hand, I'd considered using dynamic casting, but the book I'm reading says it is not recommendable. That it might be a sign of poor inheritance hierarchy design.
It seems that you didn't really understand this sentence . It might be a sign of poor inheritance so, if you want to avoid using it, then you should review your inheritance and not make CEmboss inherits from CItem, but instead have a list with CEmboss objects only.
That's why it says might, because it is not always possible to avoid it. The two suggested approaches (dynamic cast and virtual functions) have both their disadvantages:
- dynamic cast will be a bit slower (but in the most cases, you won't even notice it, unless this code is heavily called)
- virtual functions in your case make the code less readable (what is this GetOrientation function doing in my CItem class ??)
It's up to you to decide.
|
|
|
|
|
Cedric Moonen wrote: - virtual functions in your case make the code less readable (what is this GetOrientation function doing in my CItem class ??)
I don't agree on the above point (I know it is matter of taste). Doing nothing is decorous for a method and maybe useful: nobody questions (at least I hope), for instance, on empty set usefulness (BTW doing nothing is one my preferred activities ).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
I think it depends of the situation. I was thinking about the case where you could have several child classes (5 or 6) and each of them needs one or two specific methods (and those methods only make sense in the child classes). Imagine the mess it would be . And this situation is not that 'extreme'.
Of course, it all depends of the situation.
CPallini wrote: (BTW doing nothing is one my preferred activities ).
I thought it was surfing on CP
|
|
|
|
|
Hi,
I assume you want to go over the list and do GetOrientation() to each node.
If this node doesn't have 'orientation' , you want to know it doesn't have one.
So, it will return NO_ORIENTATION.
Another way -
typedef enum
{
eIT_UNDEFINED = 0,
eIT_ITEM,
eIT_EMBOSS,
eIT_ANNEAL,
} EItemType;
in CNode
EItemType m_eItemType;
int GetOrientation()
{
int result = NO_ORIENTATION;
switch (m_eItemType)
{
case eIT_EMBOSS:
{
result = ((CEmboss *) m_pItem)->GetOrientation();
break;
}
default:
break;
}
return result;
}
I can't think of any other way - if you want to do GetOrientation() on an object, it must have that method.
|
|
|
|
|
Hi, you can use dynamic_cast to cast the CItem object to a class which does know the this function.
class CNode
{...
int GetOrientation() const
{
CEmboss* pEmbossItem = dynamic_cast<cemboss*>(m_pItem);
if(pEmbossItem != NULL)
{
return pEmbossItem->GetOrientation();
}
else
{
return ERROR_VALUE;
}
}</cemboss*> This works however only on polymorphic classes, this means classes with at least one virtual function.
codito ergo sum
|
|
|
|
|
piul wrote: The question is, how do I implement a GetOrientation() function in CNode??
Probably the scenario will be clearer if you answer to the question "Why CNode needs to call GetOrientation ?". I.e. must CNode retrieve always meaningful info with such a call?
Generally speaking, there are two viable methods to overcome the problem:
(1) use RTTI [^] to identify the actual type of the item.
(2) go through polymorphism: declare a pure virtual GetOrientation method
in CItem class thus forcing both CEmboss and CAnneal to implement it.
Personally I don't like method (1), but, of course, we have to choose the one that better fit our needs...
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
This pattern presents a maintenance problem to me. What happens when you add more CItem types? How useful is CNode if the code needs to detect the type of the contents?
The solution to me is to specialize the CNode class for the different CItems it holds,
class CNode
{
public:
virtual bool process() = 0
{
}
};
class CEmbossNode : public CNode
{
public:
virtual bool process()
{
return CNode::process();
}
protected:
int GetOrientation() const { return mnOrient; }
private:
int mnOrient;
CEmboss * mpItem;
}
class CAnnealNode : public CNode
{
public:
virtual bool process()
{
}
private:
CAnneal * mpItem;
};
class CList
{
CNode * mpListHead;
}
The types are hidden behind a polynorphic interface. Adding new types requires the definition of the polymorphic interface. Each CItem knows what it is and can use special knowledge or do just the default action.
IMHO, these outwiegh the cost of the virtual function.
// edit: remove multiple EmbossNode declarations
modified on Monday, March 24, 2008 1:43 PM
|
|
|
|
|
I'm developing a game, but the graphics are simple pictures that I show, without any further graphical functionality.
I need to know what simple ways I have to show pictures.
I tried DirectX 9 textures, but it took a lot of loading time.
I'm trying using CImage but something goes wrong.
Specifically, when doing image.Draw() I get 'debug assertion failed' inside ReleaseDc() .
|
|
|
|
|
Hanan888 wrote: ...I get 'debug assertion failed' inside ReleaseDc().
What line of what file is asserting?
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
in <atlimage.h> , line 1217
inline void CImage::ReleaseDC() const throw()
{
HBITMAP hBitmap;
ATLASSUME( m_hDC != NULL );
m_nDCRefCount--;
if( m_nDCRefCount == 0 )
{
hBitmap = HBITMAP( ::SelectObject( m_hDC, m_hOldBitmap ) );
ATLASSERT( hBitmap == m_hBitmap );
s_cache.ReleaseDC( m_hDC );
m_hDC = NULL;
}
}
|
|
|
|
|
Can you show the code?
What are you calling ReleaseDC() on? The CImage object?
You shouldn't be using CImage::GetDC()/CImage::ReleaseDC() when
using CImage::Draw().
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I have a function like this
BOOL CShowAndEditSQLDlg::IsSQLKeyword( CString strSQLWord )<br />
{<br />
<br />
char * strKeyword[19] = { "SELECT", "FROM", "WHERE", "IN", "ORDER", "GROUP", "BY", <br />
"INNER", "OUTER", "JOIN", "AS", "ON", "MIN", "MAX", "AVG", "SUM", ",", "AND", "."};<br />
<br />
<br />
for ( int i =0; i < 19; i++ )<br />
if ( stricmp ( strKeyword[i], LPCTSTR(strSQLWord) ) == 0 )<br />
return TRUE;<br />
<br />
return FALSE;<br />
}
But if I Compile that code with UNICODE settings, it is giving following error.
error C2664: 'stricmp' : cannot convert parameter 1 from 'unsigned short *' to 'const char *'
Please help me.
|
|
|
|
|
Royaltvk wrote: error C2664: 'stricmp' : cannot convert parameter 1 from 'unsigned short *' to 'const char *'
Probably the error comes instead on parameter 2.
Anyway, change your code as follows
BOOL CShowAndEditSQLDlg::IsSQLKeyword( CString strSQLWord )
{
TCHAR * strKeyword[19] = { _T("SELECT"), _T("FROM"), _T("WHERE"), _T("IN"), _T("ORDER"), _T("GROUP"), _T("BY"),
_T("INNER"), _T("OUTER"), _T("JOIN"), _T("AS"), _T("ON"), _T("MIN"), _T("MAX"), _T("AVG"), _T("SUM"), _T(","), _T("AND"), _T(".")};
for ( int i =0; i < 19; i++ )
if ( _tcsicmp ( strKeyword[i], LPCTSTR(strSQLWord) ) == 0 )
return TRUE;
return FALSE;
}
OT: sorry Mark no GetBuffer here.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thank u somuch for your code
It is perfectly working.
U got my 5 Marks.
Royal.
|
|
|
|
|
Actually I got 1 , anyway, you're welcome.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
I've balanced it up with my 5 vote.
Nobody can give you wiser advice than yourself. - Cicero
.·´¯`·->Rajesh<-·´¯`·.
Codeproject.com: Visual C++ MVP
|
|
|
|
|
Ah, were you, thanks buddy!
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
CPallini wrote: OT: sorry Mark no GetBuffer here.
Hehe I can't believe that caught my eye when I glazed over your post
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
To complete with the previous answer, you can also have a look at this article[^] if you want to understand a bit better why you have that compilation error.
|
|
|
|
|
Is IsSQLKeyword() called often?
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
|
preeti sharma wrote: how can i create a toolbar on a dialog box in MFC.
By performing a basic google search[^]
Nobody can give you wiser advice than yourself. - Cicero
.·´¯`·->Rajesh<-·´¯`·.
Codeproject.com: Visual C++ MVP
|
|
|
|
|
Hi to all!
In my code I call 'AfxBeginThread' in which I fetch data from Database. I use 'theApp.DoWaitCuscor(1)' within thread to display hourglass cursor and 'theApp.DoWaitCuscor(-1)' to remove it when I'm done.
But this don't happens. Why?
P.S.
Thanks for all help
|
|
|
|
|
Don't do that inside the worker thread. Post a message from the worker thread to the GUI one and let the latter do the job.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|