Disable execution of parts of the code based on user's choice C++
I see two things:


option acquisition (a lot of control flow and ad-hoc checks to detect the user input)
operational program flow (the decisions based on it). Here I'd suggest Null Object pattern


Acquisition

At first, I'd suggest using standard library algorithms and types instead of ad-hoc program flow and casting:

std::vector&lt;std::string&gt; const args(argv+1, argv+argc);


Which you can use much easier, like:

auto find_arg    = [&amp;](auto option) { return std::find(args.begin(), args.end(), option); };


So now you can just locate an argument using find_arg("--port"). And you can build on it:

auto find_arg    = [&amp;](auto option) { return std::find(args.begin(), args.end(), option); };
auto has_flag    = [&amp;](auto option) { return args.end() != find_arg(option); };


Now you can simply do:

bool const socketsActivated = !has_flag("--nosocket");
bool const logActivated     = !has_flag("--nolog");


Note that these are immutable, so program logic is strictly simpler and more verifiable. Getting the port takes a little more effort, but can be supported generically too:

auto get_option  = [&amp;](auto option, auto default_value) -&gt; std::string {
    auto it = find_arg(option);
    if (it != args.end()) {
        it = ++it;
        if (it == args.end()) { // There was no argument
            throw std::runtime_error(std::string(option) + " requires an argument");
        }
        return *it;
    }
    return default_value;
};


So now you can write:

int main(int argc_, char *argv_[])
{
    std::vector&lt;std::string&gt; const args(argv_+1, argv_+argc_);

    auto find_arg    = [&amp;](auto option) { return std::find(args.begin(), args.end(), option); };
    auto has_flag    = [&amp;](auto option) { return args.end() != find_arg(option); };
    auto get_option  = [&amp;](auto option, auto default_value) -&gt; std::string {
        auto it = find_arg(option);
        if (it != args.end()) {
            it = ++it;
            if (it == args.end()) { // There was no argument
                throw std::runtime_error(std::string(option) + " requires an argument");
            }
            return *it;
        }
        return default_value;
    };

    std::string const port      = get_option("--port", "27013");
    bool const socketsActivated = !has_flag("--nosocket");
    bool const logActivated     = !has_flag("--nolog");


It's more legible, less error prone and very extensible.

The extra mile

When you find yourself collecting operations like has_flag, get_option you can move them to a suitable abstraction.

Here's exactly the same data + operations grouped into a CommandLineParser:

struct CommandLineParser {
    CommandLineParser(int argc, char** argv) : _args(argv+1, argv+argc) {}

    auto find_arg  (std::string const&amp; option) const {
        return std::find(_args.begin(), _args.end(), option);
    };
    bool has_flag  (std::string const&amp; option) {
        return _args.end() != find_arg(option);
    };
    std::string get_option(std::string const&amp; option, std::string const&amp; default_value) {
        auto it = find_arg(option);
        if (it != _args.end()) {
            it = ++it;
            if (it == _args.end()) { // There was no port argument
                throw std::runtime_error(option + " requires an argument");
            }
            return *it;
        }
        return default_value;
    };

    std::vector&lt;std::string&gt; const _args;
};


And now main starts like this:

int main(int argc, char *argv[])
{
    CommandLineParser clp(argc, argv);
    std::string const port      = clp.get_option("--port", "27013");
    bool const socketsActivated = !clp.has_flag("--nosocket");
    bool const logActivated     = !clp.has_flag("--nolog");


Clean as a whistle.

Null Object Pattern

Here you prevent having null objects or repeated switches by having different implementations of the same interface. You just instantiate a "do-nothing" implementation if the behaviour is disabled:

/////////////////////////////////////
// abstract interface and null-implementation
struct IServer {
    virtual void update() = 0;
};

struct NullServer : IServer {
    virtual void update() override { }; // do nothing
};

struct CommunicationServer : IServer {
    CommunicationServer(std::string) {}
    virtual void update() override {
        std::clog &lt;&lt; "Communication update\n";
    }
};

struct EchoServer : IServer {
  EchoServer(std::string) {}
    virtual void update() override {
        std::clog &lt;&lt; "Echo update\n";
    }
};


Now you can simplify the call - site:

int main(int argc, char *argv[])
{
    std::unique_ptr&lt;IServer&gt;          server(new NullServer);
    std::unique_ptr&lt;IServer&gt;          echo(new NullServer);
    std::unique_ptr&lt;IFileOperations&gt;  traceFile(new NullFileOperations);

    // parse user config
    CommandLineParser clp(argc, argv);

    if (!clp.has_flag("--nosocket")){
        server = std::make_unique&lt;CommunicationServer&gt;(clp.get_option("--port", "27013"));
        echo   = std::make_unique&lt;EchoServer&gt;("27014");
    }

    if (!clp.has_flag("--nolog")) {
        traceFile = std::make_unique&lt;FileOperations&gt;();
    }

    while (!_kbhit()) // Till the key was pressed
    {
        Sleep(25); // lower the load on CPU

        server-&gt;update();
        echo-&gt;update();
    }
}


Full Demo

Live On Coliru

#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;
#include &lt;memory&gt;
#include &lt;thread&gt;

// mocks
static void Sleep(int ms) {
    std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}

static bool _kbhit() {
    static int remain = 10;
    return remain-- == 0;
}

/////////////////////////////////////
// abstract interface and null-implementation
struct IServer {
    virtual void update() = 0;
};

struct NullServer : IServer {
    virtual void update() override { }; // do nothing
};

struct CommunicationServer : IServer {
    CommunicationServer(std::string) {}
    virtual void update() override {
        std::clog &lt;&lt; "Communication update\n";
    }
};

struct EchoServer : IServer {
  EchoServer(std::string) {}
    virtual void update() override {
        std::clog &lt;&lt; "Echo update\n";
    }
};


/////////////////////////////////////
// similar for other interfaces
struct IFileOperations { };
struct NullFileOperations : IFileOperations { };
struct FileOperations : IFileOperations {};

struct CommandLineParser {
    CommandLineParser(int argc, char** argv) : _args(argv+1, argv+argc) {}

    auto find_arg  (std::string const&amp; option) const {
        return std::find(_args.begin(), _args.end(), option);
    };
    bool has_flag  (std::string const&amp; option) {
        return _args.end() != find_arg(option);
    };
    std::string get_option(std::string const&amp; option, std::string const&amp; default_value) {
        auto it = find_arg(option);
        if (it != _args.end()) {
            it = ++it;
            if (it == _args.end()) { // There was no port argument
                throw std::runtime_error(option + " requires an argument");
            }
            return *it;
        }
        return default_value;
    };

    std::vector&lt;std::string&gt; const _args;
};

int main(int argc, char *argv[])
{
    std::unique_ptr&lt;IServer&gt;          server(new NullServer);
    std::unique_ptr&lt;IServer&gt;          echo(new NullServer);
    std::unique_ptr&lt;IFileOperations&gt;  traceFile(new NullFileOperations);

    // parse user config
    CommandLineParser clp(argc, argv);

    if (!clp.has_flag("--nosocket")){
        server = std::make_unique&lt;CommunicationServer&gt;(clp.get_option("--port", "27013"));
        echo   = std::make_unique&lt;EchoServer&gt;("27014");
    }

    if (!clp.has_flag("--nolog")) {
        traceFile = std::make_unique&lt;FileOperations&gt;();
    }

    while (!_kbhit()) // Till the key was pressed
    {
        Sleep(25); // lower the load on CPU

        server-&gt;update();
        echo-&gt;update();
    }
}


Which, without options, prints e.g.

Communication update
Echo update
Communication update
Echo update
Communication update
Echo update
Communication update
Echo update
Communication update
Echo update
Communication update
Echo update
Communication update
Echo update
Communication update
Echo update
Communication update
Echo update
Communication update
Echo update


But with --nosocket prints nothing, and with missing port prints:

terminate called after throwing an instance of 'std::runtime_error'
  what():  --port requires an argument