You will rarely need a main function in code you distribute. The primary situation where you will want to write programs that include main is when writing simple test applications. For example, you might want to write a test program to check your understanding of collections or streamable (persistent) objects.
Persistent objects rely on information inside shared libraries in order to be flattened and resurrected. This type information is appended to the end of shared libraries when the libraries are built. Programs and servers do not store the type information required for flattening and resurrecting at run time.
For example, TSetOf<TDocument> is a template class and can be used anywhere a class is required in source code. You can create an instance of TSetOf<TDocument> with the same syntax used to declare an instance of any C++ class.
TSetOf<TDocument> aDocumentSet;
Normally, each of the components in a framework making use of shared persistent objects is a shared library. You might run into trouble, though, when writing test code to see if flattening and resurrecting are working properly for a newly defined template class. The easiest way to write such a test would be as a stand-alone program.
However, the preceding declaration actually defines a new type, TSetOf<TDocument>, that is not defined in any shared libraries if the declaration appears inside the same source module that includes main. Since program modules do not have type information appended to them when they are built, there is no way at run time for aDocumentSet to be resurrected once it has been flattened and stored to memory or to a file outside the test program's address space.