There are exactly none, but there was a time during the mid- to late-90s when it was hip to implement OOP frameworks on top of C (C++ only really became a realistic option once C++98 was widely supported which took a couple of years, ...also there was such an extreme OOP hype in the 90s that it is hard to believe today - EVERYTHING had to be OOP, no matter if it made sense or not).
QEMU seems to be from around the end of that era (first release apparently in 2003), and looking at the code it looks exactly as I imagined, with meta-class pointers, constructor- and destructor-functions etc... it would almost certainly be better to use a simple non-OOP C-style, but that was an 'outdated' point of view at that time (since everything had to use that new shiny OOP paradigm).
However there is a reason to have the object model, and it was added because some things were getting out of hand. You had to write three parsers for everything you added: one for command line, one for the text-based command interface and one for the JSON API. And you had to do it once for each kind of "object" (device, network backend, disk backend, character device backend etc.). The object model is designed to let you write code just once for all three and to reuse the interface across object types.
IMHO if you deliberately use C it's because you want to keep things simple. Sometimes C++ will inevitably lead to overcomplicated designs nobody needs; there's a reason why 90's C++ feels massively outdated, while 90's C is still (mostly) accessible. C is a great way to keep the urge people have to shovel in OOP even when it doesn't really make sense. When I see some bullshit C++ code at work, I often think, "if people had to write this in C, they wouldn't have overthought this this much"...
My 2 cents is that there was a Java craze back in the '90s that basically infected all code designed in that time period, and that's how we got some very weird nonsense that in hindsight was poorly thought out. Just look at stuff like GTK+ and GObject...
It's a common thing to do in projects like this in C. While C++ solves some of the problems for larger projects, it brings so many more, it's usually not worth it. Projects of this kind, essentially, invent their own language, with their own conventions. C is just a convenient tool (given the alternatives...) to do that, as it's treated as a kind of a transpilation target. Think about languages like Haskell which essentially work like that, but went even further.
So, what typically happens is that memory allocation, I/O and concurrency need to be done differently from how the language runtime wants to do that. So, at this point, you basically throw away most of the existing language runtime. From my recent encounters with different bugs in QEMU, I imagine that they really, really need a lot of customization in how memory is allocated (my particular case was that QEMU was segfaulting when running ldconfig in aarch64 emulation, which turned out to be due to ldconfig having some weird custom-made memory allocation pattern which QEMU cannot account for.) It's easier to fight this battle with C than it is with C++.
In other words, if you don't want the language runtime, if you don't want C++ templates, smart pointers, classes, lambdas, exceptions etc. But, you want to be able to manage memory for eg. realtime kind of system... simply removing all the unwanted stuff from C++ is harder than it is with C.
And, if you did want some / all of those features of C++, there are saner languages to have that (and you'd pay for it by having to drag in their runtime and conventions). Before Rust was a thing, I've seen people choose D instead, for example, as a kind of middle ground between the asceticism of C and unnecessary excess of C++.
Sure, Rust is better than C++ in some ways. You can have a legitimate debate about C++ versus Rust. There can be no debate about C versus C++: the latter is better in every single way.
> unnecessary excess of C++.
Is the unnecessary excess of C++ in the room with us right now?
Again, you don't have to use any part of C++ you don't like. A few minor spelling differences aside, it remains a superset of C. Using C++ not C will not hurt you in any project whatsoever.
C is simpler because you don't need to remove any of that stuff, because it's not there to begin with.
My argument about Lisp doesn't say that anyone should use Lisp instead, it just points out that people making the choice between C and C++ aren't concerned by how easy it is to build new languages using the language building tools of C or C++ because both are very bad at it. Had the objective of building a new language been the primary objective of such projects, they'd be using a language with superior language building tools (not necessarily Lisp, there are many alternatives, it's just that neither C nor C++ are good at it).
But yeah broadly speaking it's a terrible idea.