Emulator for representing hardware and operating systems This is an emulator I am currently re-writing for my Operating Systems course. It is a simple emulator that is supposed to represent hardware, OS, etc. It is strictly for learning purposes and I want to propose my solution to the teacher as a method of modern C++ (since his solution is more "C with classes"). 

However, before I do that, I would like to make sure I don't embarrass myself with bad code.

Right now I'm debating on my association between hardware and OS. They are currently written like so:

// Hardware.h
class OS;
class Hardware : boost::noncopyable
{
    friend class OS;

private:
    Hardware(OS *os);

    void load_job(boost::shared_ptr&lt;Job&gt; job);
    void run_job();

private:
    void execute_instruction(Instruction const&amp; instruction);
    void handle_interrupt(Instruction const&amp; trap);

private:
    enum { NumberOfRegisters     = 32 };
    enum { InstructionMemorySize = 1024 };
    enum { DataMemorySize        = 1024 };

    OS                            *m_pOS;

    std::vector&lt;int&gt;               m_Registers;
    boost::ptr_vector&lt;Instruction&gt; m_InstructionMemory;
    std::vector&lt;int&gt;               m_DataMemory;

    boost::optional&lt;int&gt;           m_Counter;
};


// OS.h
class Hardware;
class OS : boost::noncopyable
{
    friend class Hardware;

public:
    OS();

    // Load jobs
    void boot();
    // Execute jobs
    void run();

private:
    // "Interrupts"
    void trap_halt(int status);
    void trap_getw(int&amp; receiver);
    void trap_putw(int value);
    void trap_dump();

    void time_elapsed();

private:
    void get_next_job();

private:
    boost::scoped_ptr&lt;Hardware&gt; m_pHardware;
    boost::scoped_ptr&lt;Parser&gt;   m_pParser;

    boost::ptr_deque&lt;Job&gt;       m_Jobs;
    boost::ptr_deque&lt;Job&gt;       m_JobsInProgress;
};


The question is:  I don't want the Hardware to be accessible by any other class other than OS. Declaring Hardware private and friending OS is a step in the right direction, but it bothers me that OS now has access to all functions. Is there a way I can restrict OS?

Also, I did some researching on callbacks, but the C++ FAQ suggests that you shouldn't make callbacks to member functions of a class. Are there other solutions such that my Hardware class does not need a pointer to OS in order to call its functions? 

Secondly, I'm wondering, at what point does the pImpl idiom become a viable solution? I mean, how large does a class have to be, or how many includes must it have, to seriously consider moving the class into a struct?
That's not what friends are for. Friends are for tightly integrated classes which need to be able to play with each other's private data. OS and Hardware are not tightly related; they interact through a specifically designed interface.

If you don't want other classes besides OS to call the hardware functions, don't write code in those other classes which call the hardware functions. Better yet, simply only give the Hardware pointer to the OS class so only it can call the hardware functions.

For callbacks have a look at the boost::function library. It will allow you to create callbacks to the OS methods. You can create pointers to methods but you need both the method pointer and the object point for it to work. Boost::function hides all of this behind the scenes. 

pImpl is workaround because C++ is such a silly language. Its purpose is to make it so that you do not have to recompile the header file whenever the private members of the class change. More modern languages essentially do this automatically for all classes. pImpl makes sense only when your compile times get too large. A class project probably doesn't get large enough for that to be a big concern.