title: Initialize object from another one in C++
body: <p>In my project I have Resource objects which can be loaded and reloaded from different formats. Loading algorithms are implemented in different ResourceLoader subclasses.</p>
  
  <pre><code>class Resource
  {
  private:
  
      // Not for client access    
      Type1 InternalData1;
      Type2 InternalData2;
      TypeN InternalDataN;
  
      ResourceLoader Loader;
  
  public:
  
      // Any client interface
      void UseResource();
  };
  
  class ResourceLoader
  {
  public:
  
      void Load(Resource&amp; R) = 0;
  };
  
  class ResourceLoaderFormat1: public ResourceLoader
  {
  public:
  
      void Load(Resource&amp; R) { ...loads Resource from Format1... }
  };    
  
  class ResourceLoaderFormat2: public ResourceLoader
  {
  public:
  
      void Load(Resource&amp; R) { ...loads Resource from Format2... }
  };
  </code></pre>
  
  <p>Loader reads input in a given format and initializes its target Resource object R. Loader is stored inside a resource, so if resource becomes invalid, it reloads itself using the loader stored.</p>
  
  <p>The question is how a Loader should initialize a Resource?</p>
  
  <ol>
  <li>Make all InternalData fields public. It grants client access to them, which is not good.</li>
  <li>Make Loader a friend of Resource. Each new loader for a particular format will be added to a resource header, killing extensibility, and requiring any programmer who writes an extension to touch base code.</li>
  <li>Provide setter for each InternalData. Not far from making all them public, as any client may change data it must not change.</li>
  <li>Provide Resource::Setup(InternalData1, InternalData2, InternalDataN), or wrap them all in some structure and pass that structure. Same as 3. except that all fields are set at a time.</li>
  </ol>
  
  <p>The problem is that a Resource class fields must be accessible for write from extensible set of classes and must be inaccessible for write from a client code. Is there any good OOP solution? Thanks.</p>