- 主题:异常是 C++ 最烂最烂最烂最烂最烂最烂的设计
需要搭配 RAII 来使用。
异常不好用的原因来源于现实世界的复杂性。
写程序如果不用考虑异常流程那该多好啊。但问题是不行。
【 在 speedboy2998 的大作中提到: 】
: 烂透了。
--
FROM 27.152.110.*
我写业务逻辑是不用异常的。包括 python 也不用。
写框架才会用上异常。
【 在 hehao 的大作中提到: 】
: 主要是不同轮子用异常和返回值等不同的机制
: 混合使用时容易造成困扰
--
FROM 27.152.110.*
你关掉了 new 操作符抛出的 bad_alloc 异常吗?不在命令行里面关的话,还是可能随时抛异常的啊。
所以写 C++,无论什么情况都得做 RAII
以前 RAII 不好做是因为有回调函数跳来跳去。在一个函数里面创建的对象,没法在函数内释放掉。只能用大量的 shared_ptr<> 管理对象。
现在好办。我自从 2018 年之后就开始使用 C++ 协程编程,而 c++20 也已经有了协程。以后 shared_ptr<> 这一类智能指针的使用场景就少多了。
【 在 tom6bj 的大作中提到: 】
: 我搞嵌入式,也不用异常,不用iostream,上位机才用.
: 我写业务逻辑是不用异常的。包括 python 也不用。
: 写框架才会用上异常。
: ...................
--
FROM 27.152.110.*
这种没办法,只能丢到线程池里面去搞。用协程+线程池总比多线程强吧。
如果这些程序库有回调函数的话,还可以转成协程阻塞函数。
我实现过一个版本。
template<typename Result>
Result qAwait(Func asyncFunc)
{
shared_ptr<Event> event(new Event);
auto callback = [event](Result r) { event->set(r); };
asyncFunc(callback);
return event->wait();
}
上面是伪代码。但是通过 Event 这个工具类,就可以把任何异步函数转成同步的。懂 win32api 和 python 的应该都知道这个 Event 是个啥我这里就不细说了。
于是后续就可以这样调用:
auto r = qAwait(mysql_connect, args...);
我实现成功的 Qt 版本。使用方式是这样的:
animation1->start();
qAwait(animation1, SIGNAL(finished());
button->show();
qAwait(button, SIGNAL(clicked());
button->hide();
animation2->start();
于是我可以在协程里面阻塞等待用户的点击事件再继续。以上代码意思很清楚吧,先执行动画1,结束之后等待用户点一下按钮,再继续执行动画2.
【 在 stub 的大作中提到: 】
: 使用什么协程库呢, 使用协程, 如果想完全不堵塞, 还需要实现各种对应的协程客户端, 比如http, grpc, redis, mongo, mysql等, 如果不实现对应的协程客户端, 协程的性能是大打折扣的
--
修改:hgoldfish FROM 27.152.110.*
FROM 27.152.110.*
对。。你可以搜一下 python 的 threading.Event 类型,以及 win32api 的 CreateEvent() 函数。
这个工具类以前是用于线程的。我以前写 Java 的时候也经常用。
本质上个 condition + flag
struct Event<T>
{
Condition cnd;
bool flag;
T value;
void set(T v) {
flag = true;
value = v;
cond.notify();
}
T await() {
if (!flag)
cond.wait();
return value;
}
}
很简单吧。但是它的意义很重大。对于线程 Condition 的实现一般是现成的。对于协程,实现等价的 Condition 相当不容易。是大多数协程库的重大挑战。有兴趣你们可以实现一个 c++20 coroutine 的版本。有了 Event 之后,立即可以把大多数现有的 C++ 异步程序库给接入到 c++20 coroutine 里面。
注意,实现 coroutine condition 需要事件循环。
【 在 stub 的大作中提到: 】
: 不太清楚event,上面的逻辑是不是就是在回调函数中唤醒协程
--
修改:hgoldfish FROM 120.41.212.*
FROM 120.41.212.*
stl 里面也有啊。
【 在 tom6bj 的大作中提到: 】
: mcu啊...
: 基本不用new, 大部分用全局对象, 少数用unique_ptr, 够用了
: 你关掉了 new 操作符抛出的 bad_alloc 异常吗?不在命令行里面关的话,还是可能随时抛异常的啊。
: ...................
--
FROM 120.41.212.*