条件运算符的局限性?:

ori*_*n93 6 c++ conditional destructor conditional-operator operator-keyword

我正在使用GCC 4.5,并观察到非常奇特的行为.我想知道这个运算符是否有什么我不完全理解的东西.我以为我精通C++.我有一个Wnd用于Windows HWND对象的精简C++包装类,它具有一个实现的强制转换操作符operator HWND ....

如果我像这样使用条件运算符(给定输入Wnd *p和示例函数SetParent(HWND)):

SetParent((p!=NULL) ? (HWND)(*p) : NULL)
Run Code Online (Sandbox Code Playgroud)

父级正确设置为NULLp依赖.这就是我所期待的.但是,如果敢于懒惰并写下:

SetParent(p ? *p : NULL)
Run Code Online (Sandbox Code Playgroud)

事情变得混乱.在运行GDB之后,我发现p在调用之后调用了析构函数SetParent.有什么想法在这里发生了什么?

编辑 这是我的Wnd课程:

class Wnd{
        HWND m_hwnd;        ///< the actual handle
        WndFake *fake;      ///< store state here if we do not have a handle
    public:
        virtual ~Wnd();
        //contructor s
        Wnd(HWND wnd=NULL):m_hwnd(wnd),fake(NULL){}
        Wnd(DWORD sty,const jchar *title,const RECT &sz);
        operator HWND(){return m_hwnd;}
        operator HWND() const {return m_hwnd;}
    }
Run Code Online (Sandbox Code Playgroud)

Öö *_*iib 4

我怀疑你的 Wnd 也有非显式转换构造函数,它需要 HWND 甚至 int ?如果是这样,请明确说明。

您的 Wnd 可能没有声明复制构造函数和运算符=?将它们声明为私有并且不定义它们。

还要删除operator HWND成员函数并将HWND hwnd() const;其添加到 Wnd. 然后代码看起来可读如下:

Setparent( p ? p->hwnd() : NULL );
Run Code Online (Sandbox Code Playgroud)

我相信当这些 mods 完成后你会发现你的 Wnd 出了什么问题。

问题本身就出现了,因为 : in ?: 两边的操作数必须是相同的类型,因此 NULL (0) 可以以某种方式转换为 Wnd。因此 *p 的临时副本被制作为 ?: 的返回值,然后对其调用运算符 HWND。