 <p>In base class, create abstract virtual method that returns some kind of "ID". (string, int, enum, whatever).</p> <p>In "save" method, write ID first, for all classes. You could embed ID writing into base class, so derived classes won't override this behavior.</p> <pre><code>typedef SomeType ClassId; class Serializeable{ protected: virtual ClassId getClassId() const = 0; virtual void saveData(OutStream &amp;out) = 0; public: void save(OutStream &amp;out){ out &lt;&lt; getClassId(); saveData(out); } }; </code></pre> <p>Make a factory, that constructs required class given its ID.</p> <p>--edit--</p> <p>Example with factory (C++03 standard):</p> <pre><code>#include &lt;map&gt; #include &lt;string&gt; #include &lt;iostream&gt; #include &lt;QSharedPointer&gt; #include &lt;utility&gt; typedef std::string ClassId; typedef std::ostream OutStream; class Serializeable{ protected: virtual void saveData(OutStream &amp;out) = 0; public: virtual ClassId getClassId() const = 0; void save(OutStream &amp;out){ out &lt;&lt; getClassId(); saveData(out); } virtual ~Serializeable(){ } }; class Derived: public Serializeable{ protected: virtual void saveData(OutStream &amp;out){ out &lt;&lt; "test"; } public: virtual ClassId getClassId() const{ return "Derived"; } }; typedef QSharedPointer&lt;Serializeable&gt; SerializeablePtr; //basically std::shared_ptr SerializeablePtr makeDerived(){ return SerializeablePtr(new Derived()); } class ClassFactory{ protected: typedef SerializeablePtr (*BuilderCallback)(); typedef std::map&lt;ClassId, BuilderCallback&gt; BuilderMap; BuilderMap builderMap; template&lt;class C&gt; static SerializeablePtr defaultBuilderFunction(){ return SerializeablePtr(new C()); } public: SerializeablePtr buildClass(ClassId classId){ BuilderMap::iterator found = builderMap.find(classId); if (found == builderMap.end()) return SerializeablePtr();//or throw exception return (*(found-&gt;second))(); } void registerClass(ClassId classId, BuilderCallback callback){ builderMap[classId] = callback; } template&lt;typename T&gt; void registerClassByValue(const T &amp;val){ registerClass(val.getClassId(), ClassFactory::defaultBuilderFunction&lt;T&gt;); } template&lt;typename T&gt; void registerClassWithTemplate(ClassId classId){ registerClass(classId, ClassFactory::defaultBuilderFunction&lt;T&gt;); } }; int main(int argc, char** argv){ ClassFactory factory; std::string derivedId("Derived"); factory.registerClass(derivedId, makeDerived); SerializeablePtr created = factory.buildClass(derivedId); created-&gt;save(std::cout); std::cout &lt;&lt; std::endl; Derived tmp; factory.registerClassByValue(tmp); created = factory.buildClass(derivedId); created-&gt;save(std::cout); std::cout &lt;&lt; std::endl; factory.registerClassWithTemplate&lt;Derived&gt;(derivedId); created = factory.buildClass(derivedId); created-&gt;save(std::cout); std::cout &lt;&lt; std::endl; return 0; } </code></pre> <p><code>QSharedPointer</code> is smart pointer class from Qt 4, roughly equivalent to <code>std::shared_ptr</code>. Use either <code>std::shared_ptr</code> or <code>boost::shared_ptr</code> instead of <code>QSharedPointer</code> in your code.</p>