我试图更好地理解处理继承时的抛出-捕获机制。
我试图解决的问题是,如果在构造派生类时,首先构造的基类抛出异常,将会发生什么情况。
#include <stdexcept>
#include <iostream>
class Base
{
public:
Base()
{
throw std::runtime_error("test");
}
};
class Derived : public Base
{
public:
Derived() try : Base()
{
}
catch (std::runtime_error& e)
{
std::cout << "Base throws an exception : " << e.what() << std::endl;
}
};
int main ()
{
Derived temp;
return (0);
}
Run Code Online (Sandbox Code Playgroud)
运行编译后的代码 (g++ std=11) 后,我收到以下消息:
基类抛出异常:测试
抛出“std::runtime_error”实例后调用终止
什么():测试
已中止(核心转储
我的 Base 抛出的异常被 Derived 构造函数的 try-catch 捕获,但由于某种原因,抛出的异常并没有停止在那里,为什么会这样,以及如何解决这个问题?
不管怎样,如果有更好的方法来处理派生类构造时基类可能抛出的异常,我愿意接受建议。
为了获得一些乐趣和自我教育,我正在尝试编写自己的X11工具包。这让我很沮丧。
我有一个传统的组合框显示元素,一个有下拉菜单的典型组合框,就像所有流行的工具包一样。
对于下拉弹出列表,我创建了一个新窗口,它是根窗口的子窗口,适当地位于主组合框显示元素下方。
下拉弹出列表是一个单独的窗口,该窗口实现了基于键盘的导航,以选择下拉列表中的各个条目。
因此,我使用SetInputFocus将输入焦点设置为打开后的弹出窗口。
我发现,执行此操作后,窗口管理器将重新绘制主窗口的框架,以指示其不再具有输入焦点。从技术上讲,这是正确的,但是在主流工具包中我看不到相同的结果,在可比较的情况下,主窗口的框架显示它仍然具有输入焦点。
对于弹出窗口,除了设置覆盖重定向之外,我还想尽一切办法告诉窗口管理器发生了什么:在弹出窗口的WM_HINTS中设置窗口组领导者ID,设置WM_TRANSIENT_FOR,并将_NET_WM_WINDOW_TYPE设置为_NET_WM_WINDOW_TYPE_COMBO; 所有这些似乎都不起作用(我验证了通过xprop正确设置了属性)。
看来我必须将输入焦点保持在组合框窗口中,并将按键和按键释放事件转发到下拉弹出窗口中的显示元素,这感觉很笨拙。我是否在忽略某个属性,该属性会告诉窗口管理器弹出窗口的输入焦点已链接到主窗口的窗口(除了我提到的那些窗口之外),因此可以保持绘制主窗口的框架以显示其具有输入焦点。输入焦点实际上在弹出窗口中?
根据N3337工作草案(与已发布的ISOC++ 11标准最相似的草案),答案最多只有一个.
N3337:
最多一个用户定义的转换(构造函数或转换函数)隐式应用于单个值.
Run Code Online (Sandbox Code Playgroud)[ Example: struct X { operator int(); }; struct Y { operator X(); }; Y a; int b = a; // error // a.operator X().operator int() not tried int c = X(a); // OK: a.operator X().operator int() —end example ]
但根据使用gcc(Ubuntu 4.8.4-2ubuntu1~14.04)4.8.4编译main.cpp并在Ubuntu 14.04.3 LTS中使用引用语句运行a.out的结果,答案最多不是一个.
main.cpp:
#include <iostream>
struct As
{
operator int(){ std::cout<<"operator As::int()"<<std::endl; return 1; }
};
struct Bs
{
operator int(){ std::cout<<"operator …Run Code Online (Sandbox Code Playgroud)