look at "dc.SelectObject(&pen)" and "dc.SelectObject (&brush)",here no matter I use "&" or not it results the same. why is that?

void CMainWindow::OnPaint ()
{
    CPaintDC dc (this);
    CBrush brush (RGB (255, 0, 0));
    CPen pen (PS_NULL, 0, (RGB (0, 0, 0)));
    
    dc.SelectObject(&pen);
    dc.SelectObject (&brush);
    dc.Ellipse (0, 0, 200, 100);
}

Dani AI

Generated

Brief answer and safe practice: prefer passing the address (the &) and explicitly handle the object that SelectObject returns. That makes your intent clear, avoids relying on implicit conversions, and prevents subtle lifetime/restore bugs that show up later. correctly pointed out why omitting & can still "work", and 's reminder about warnings is relevant — but the robust pattern is explicit address + restore.

A minimal safe pattern to follow (capture the previously selected object and restore it before leaving scope):

CPen pen(...);
CPen* pOldPen = dc.SelectObject(&pen);   // save old pen
// draw using dc
dc.SelectObject(pOldPen);                // restore old pen

Do not delete or let a GDI object go out of scope while it is still selected into a DC. Creating a pen/brush, selecting it into a DC, and then allowing the object to be destroyed (or selecting another object without restoring the original) can lead to resource leaks or drawing glitches.

Troubleshooting tips: compile with a high warning level (for MSVC use /W4 or /Wall) to reveal any implicit-conversion or overload issues; run with a GDI object leak checker or watch resource usage if drawing code runs frequently; avoid selecting temporary objects or objects shared across threads. If the compiler chooses a surprising overload, disambiguate by being explicit (use the address form or an explicit cast) rather than relying on implicit conversions.

Recommendation: follow the explicit-address + save/restore idiom in paint handlers. It is clear, maintainable, and avoids the subtle runtime and resource problems that implicit conversions and overload resolution can introduce.

Recommended Answers

All 3 Replies

> here no matter I use "&" or not it results the same.
Well one or the other is going to produce at least a compiler warning. Choose the one which compiles cleanly.

> why is that?
Sometimes, despite the programmers' best efforts to make a mess of it, it still manages to produce the expected result.
Never confuse "expected results" and "bug free" as meaning the same thing.

acctually no warning at all.

But which one is the optimal one here? as you recommend

It works because CBrush and CPen are derived from class CGdiObject, which has an operator void* that is being called when you leave out the & symbol. So the & symbol in this case is optional.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.