Emudore: a C64 emulator written from scratch using C++11 and SDL2
This is a cool project with nice, simple code. However, the submission&#x27;s title (perhaps counter to the README) makes it seem like a good example of C++11, and I would caution against using it that way. From a cursory examination, and with all due respect to the author, this code is more classical C++ with a few uses of C++11 features than it is representative of how modern C++ (at the time of C++11&#x27;s publication) should be written. There are a few areas where the code could be updated: adding tests, avoiding manual memory management, making it so objects cannot be created in invalid states that would cause crashes, const correctness, etc.<p>By way of explanation, I&#x27;ll focus on just the issue of manual memory management. Simplifying a bit, consider this part of the C64 class&#x27;s implementation:<p><pre><code>    C64::C64()
    {
      cpu_  = new Cpu();
      mem_  = new Memory();
      cia1_ = new Cia1();
      ...

      cpu_-&gt;memory(mem_);
      cpu_-&gt;reset();
      ...

      cia1_-&gt;cpu(cpu_);
      ...

      mem_-&gt;cia1(cia1_);
      ...
    }

    C64::~C64()
    {
      delete cpu_;
      delete mem_;
      delete cia1_;
      ...
    }
</code></pre>
The contract in this code is that a C64 owns the chips, the chips are born when the C64 is instantiated, and when the C64 dies, the chips all die along with it. There are two approaches for making this contract explicit, one is to simply not use pointers and references at all:<p><pre><code>    Cpu cpu_;
    Memory memory_;
    Cia1 cia1_;
</code></pre>
But this does mean we can&#x27;t use polymorphism within the C64 class, we don&#x27;t have nullability, and we can&#x27;t replace the instances. The code doesn&#x27;t leverage any of these, so that may be an appropriate choice. However, if we need any of those things, we can instead use the appropriate smart pointer:<p><pre><code>    std::unique_ptr&lt;Cpu&gt; cpu_;
    std::unique_ptr&lt;Memory&gt; memory_;
    std::unique_ptr&lt;Cia1&gt; cia1_;
</code></pre>
In either case, C64&#x27;s destructor is no longer necessary. The other classes still take raw pointers (e.g., `Cpu*`) because they do not own the objects they receive and do not dictate lifetimes.<p>It&#x27;s worth mentioning that many people would use `std::shared_ptr` here instead, but I think that&#x27;s abuse that leads you towards circular references (memory leaks): the Cpu doesn&#x27;t own its Memory, they just have their lifetimes managed exterior to them. This would actually come up with the existing design (if shared ownership were used), since the object dependency graph (which is perhaps another issue) has several circular dependencies.