While misreading the beginning of Stage I of this classic paper by Ken Thompson, I decided to create program that replicates itself.Let's say this program is called Replicator.exe. Upon running it once, it will create a new executable, Replicator_1.exe. Upon running either of those executables, a new executable, Replicator_2.exe, will be created.Some of the things I am interested in:De-coupling the Windows dependent logic.  Naming (I feel like some of my variable and function names are bad).  Anything else that seems odd or better ways to do this.Please note that I wrote this with Visual Studio 2012, so I only have access to a limited amount of C++11 features. For your own safety, please do not try to put the contents of main() into an infinite loop. This is the main driver:Driver.cpp#include Replicator.h#include <algorithm>#include <fstream>#include <iterator>#include <string>template <class OutIter>OutIter copy_file (const std::string &filepath, OutIter out, std::ios::openmode open_flags = std::ios::in) ;int main (){    namespace ff = fun_fs ;    const std::string filepath = ff::process_path () ;    const std::string filepath_new = ff::unique_filename (filepath) ;    std::ofstream file (filepath_new, std::ios::binary) ;    copy_file (filepath, std::ostream_iterator <char> (file), std::ios::binary) ;    return 0 ;}template <class OutIter>OutIter copy_file (const std::string &filepath, OutIter out, std::ios::openmode open_flags){    std::ifstream file ;    file.open (filepath, open_flags) ;    if (!file.good ()) {        return out ;    }    file.unsetf (std::ios::skipws) ;    auto begin = std::istream_iterator <char> (file) ;    auto end = std::istream_iterator <char> () ;    auto new_out = std::copy (begin, end, out) ;    return new_out ;}These are some helper functions:Replicator.h#pragma once#ifndef REPLICATOR_H#define REPLICATOR_H#include <string>namespace fun_fs{    std::string process_path () ;    std::string unique_filename (std::string filename) ;}#endifReplicator.cpp#include Replicator.h#include <string>#include <system_error>#include <utility>#include <Windows.h>namespace fun_fs{    static std::pair <std::string, std::string> split_file_extension (const std::string &filename) ;    static std::string increment_count (const std::string &filename) ;  }std::string fun_fs::process_path (){    std::string path (500, ' ') ;    DWORD dw = ::GetModuleFileName (nullptr, &path[0], path.size ()) ;    // Do not mistake hidden files for file extensions.    if (dw == 0 || dw == path.size ()) {        std::error_code ec (::GetLastError (), std::system_category ()) ;        throw std::system_error (ec, ::GetModuleFileName () failed.) ;    }    path.resize (dw) ;    return path ;}std::string fun_fs::unique_filename (std::string filename){    auto file_and_extension = split_file_extension (filename) ;    std::string filename_part = std::move (file_and_extension.first) ;    const std::string file_extension = std::move (file_and_extension.second) ;    do {        filename_part = increment_count (filename_part) ;        filename = filename_part + file_extension ;    } while (::GetFileAttributes (filename.data ()) != INVALID_FILE_ATTRIBUTES) ;    return filename ;}// example: name.txt -> {name, .txt}// example: name -> {name, }static std::pair <std::string, std::string> fun_fs::split_file_extension (const std::string &filename){    std::string file_extension ;    auto index = filename.rfind ('.') ;    // ignore hidden files    if (index != 0 && index != std::string::npos) {        return std::make_pair (filename.substr (0, index), filename.substr (index)) ;    }    return std::make_pair (filename, ) ;}// example: name -> name_1// example: name_2 -> name_3// example: name_2cool -> name_2cool_1static std::string fun_fs::increment_count (const std::string &filename){    const std::string start_count = 1 ;    auto index = filename.rfind ('_') ;    if (index == (filename.size () - 1)) {        return filename + start_count ;    }    else if (index != std::string::npos) {        const std::string possible_number = filename.substr (index + 1) ;        std::size_t end_of_conversion = 0 ;        try {            int number = std::stoi (possible_number, &end_of_conversion) ;            if (end_of_conversion == possible_number.size ()) {                return filename.substr (0, index + 1) + std::to_string (number + 1) ;            }        }        catch (std::invalid_argument) {            // do nothing...        }    }     return filename + _ + start_count ;}
Program that replicates itself
c++;c++11;portability
De-coupling platform dependent code:You have very few Windows dependent tasks in your code as it stands.If I didn't miss anything, the only functions that perform system callsare process_path() and unique_filename(). I would start of the decoupling by defining a class, instead of loose functions, and adopt a simple inheritance structure to separate the platform specific tasks into a child class.It would be a lot nicer to define a base class for the portable operations, similar to:class Replicator {public:    // This being the only method the client calls.    void replicateSelf();    // Might be a default, empty...    virtual ~Replicator();protected:    // These are the platform dependent services, implemented by the specialized class.    virtual std::string processPath() = 0;    virtual std::string uniqueFilename(const std::string & filename) = 0;private:    // The other helper methods...};// A factory function. Could also be a static member function of Replicator.std::unique_ptr<Replicator> CreateReplicator(){#if WINDOWS    return std::unique_ptr<Replicator>( new WindowsReplicator );#elif LINUX    return std::unique_ptr<Replicator>( new LinuxReplicator );#else    #error Missing implementation!#endif }And the platform specific class would have to do very little, just implement the two virtual methods:class WindowsReplicator : public Replicator{    std::string processPath()    {        // calls GetModuleFileName()        ...    }    std::string uniqueFilename(const std::string & filename)     {        // calls GetFileAttributes()        ...    }};Client code would use it like this:int main(){    std::unique_ptr<Replicator> replicator = CreateReplicator();    replicator->replicateSelf();}With this setup, you would already achieve a very good separation of the platformspecific parts and the portable parts, plus have your code ready for porting to another system.Virtual methods, or dynamic dispatch, however, are normally associated with dynamic runtimebehavior. Meaning that virtual methods are very good when you want to switch the underlayinglogic while the program is running. In this case, the platform does not change during runtime.A Replicator is always a WindowsReplicator or a LinuxReplicator, or whatever.So you could instead of using virtual methods be using a form of static dispatch. CRTP comes to mind in this case. I'll leave it to you to further explore theconcept and maybe apply it. Once you create the interface class, changing it to use CRTP is easy.Side note:As Loki Astari suggested in a comment, you might very well avoid the dynamic allocation inside CreateReplicator() by making Replicator an implicit singleton. The program will never require more than one instance of the class. So another option for the factory would be something like this:Replicator & GetReplicatorInstance(){#if WINDOWS    static WindowsReplicator rep;    return rep;#elif LINUX    static LinuxReplicator rep;    return rep;#else    #error Missing implementation!#endif }In C++ 11, initialization order is also thread safe, by the way.