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);
}

> 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.