Simple Encryption for Strings I have written this code for practice. Here we will enter the number by which we want to shift alphabets.
For eg.


  Enter by how many numbers you want to shift alphabets: 4
  
  Enter string: Programmer C++
  
  Encrypted String: Lnkcnwiian Y++
  
  Decryted String: Programmer C++


Review this code and suggest better C++11 and C++14 alternatives.

#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;unordered_map&gt;

class Cipher
{
    unsigned n;
    const std::vector&lt;char&gt; alphabetL { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
      'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
      'X', 'Y', 'Z' };
    const std::vector&lt;char&gt; alphabetS { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
      'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
      'x', 'y', 'z' };
    std::unordered_map&lt;char, char&gt; shiftByNL;
    std::unordered_map&lt;char, char&gt; shiftByNS;

  public:
    Cipher(unsigned n = 0);
    std::string encrypt(std::string&amp;);
    std::string decrypt(std::string&amp;);

  private:
    char byValue(const char); //Find by value
};

Cipher::Cipher(unsigned n)
{
    for (int i = 0; i &lt; n; i++)
    {
        shiftByNL.insert(std::make_pair(alphabetL[i], alphabetL[(26 - n) + i]));
        shiftByNS.insert(std::make_pair(alphabetS[i], alphabetS[(26 - n) + i]));
    }
    for (int i = n; i &lt; 26; i++)
    {
        shiftByNL.insert(std::make_pair(alphabetL[i], alphabetL[i - n]));
        shiftByNS.insert(std::make_pair(alphabetS[i], alphabetS[i - n]));
    }
}

char Cipher::byValue(const char value)
{
    for (auto itL = shiftByNL.begin(), itS = shiftByNS.begin();
          itL != shiftByNL.end(), itS != shiftByNS.end(); ++itL, ++itS)
    {
        if (itL-&gt;second == value)
        {
            return itL-&gt;first;
        }
        else if (itS-&gt;second == value)
        {
            return itS-&gt;first;
        }
    }
    //not an alphabet
    return value;
}

std::string Cipher::encrypt(std::string&amp; original)
{
    std::string encrypted;
    std::size_t len = original.length();
    for (std::size_t i = 0; i &lt; len; i++)
    {
        if (original[i] == ' ')
        {
            encrypted = encrypted + ' ';
        }
        else if (shiftByNS.find(original[i]) != shiftByNS.end())
        {
            auto search = shiftByNS.find(original[i]);
            encrypted = encrypted + search-&gt;second;
        }
        else if (shiftByNL.find(original[i]) != shiftByNL.end())
        {
            auto search = shiftByNL.find(original[i]);
            encrypted = encrypted + search-&gt;second;
        }
        else //not an alphabet
        {
            encrypted = encrypted + original[i];
        }
    }
    return encrypted;
}

std::string Cipher::decrypt(std::string&amp; encrypted)
{
    std::string decrypted;
    std::size_t len = encrypted.length();
    for (std::size_t i = 0; i &lt; len; i++)
    {
        if (encrypted[i] == ' ')
        {
            decrypted = decrypted + ' ';
        }
        else
        {
            char key = byValue(encrypted[i]);
            decrypted = decrypted + key;
        }
    }
    return decrypted;
}

int main()
{
    unsigned num;
    std::cout &lt;&lt; "Enter by how many numbers you want to shift alphabets: ";
    std::cin &gt;&gt; num;
    std::cin.ignore();
    Cipher cipher(num);
    std::string str;
    std::cout &lt;&lt; "Enter string: ";
    std::getline(std::cin, str);
    std::string res = cipher.encrypt(str);
    std::cout &lt;&lt; "Encrypted String: ";
    std::cout &lt;&lt; res &lt;&lt; '\n';
    std::cout &lt;&lt; "Decryted String: ";
    std::string decrypted = cipher.decrypt(res);
    std::cout &lt;&lt; decrypted &lt;&lt; '\n';
}
I don't think you should hard-code the length of alphabet as 26 here:
for (int i = n; i &lt; 26; i++)

Doing so will make it harder to adapt this code to languages with a different number of letters.  Instead, prefer to use alphabetL.size() and alphabetS.size() (and probably use separate loops, as some languages don't have the same number of upper-case and lower-case letters).

It's probably advisable to test that n is less than the alphabet length (or to reduce it modulo length before using), and perhaps reject a zero shift (which is what we call a &quot;weak key&quot; for this cipher).

decrypt() is much slower than encrypt, because it does a search for every character.  What you really want is a pair of maps, but not lowercase and uppercase - instead you want forward and reverse (with both upper and lower in the same map).  In fact, I'd go further; allow negative values for the shift, and then we can create a separate Cipher object for the decryption.

Constructor that can accept a single argument should be explicit.  I don't think a default of 0 is a good choice (see my comment about weak keys).  Also, prefer initialization to assignment in constructors (GCC will warn, with -Weffc++).

Cipher::n is never initialized or used - we can drop that member.  Also, the two constant vectors don't need to be members - they are used only in the constructor, where they can be shared between all instances.  We can simplify further by making them string literals.

encrypt() and decrypt() both take a modifiable reference to their input, but it seems they should not modify the input string.  You could pass a reference to const string, but I think it might be easier to accept a copy by value, and modify the copy.
Also, they shouldn't be modifying the Cipher object, so they can be declared const.

Modified code
Here's what I came up with:
#include &lt;algorithm&gt;
#include &lt;unordered_map&gt;

class Cipher
{
    const std::unordered_map&lt;char, char&gt; map;

public:
    explicit Cipher(int n);
    std::string encrypt(std::string) const;

private:
    static std::unordered_map&lt;char, char&gt; make_map(int n);
};


Cipher::Cipher(int n)
    : map{make_map(n)}
{}

std::unordered_map&lt;char, char&gt; Cipher::make_map(int n)
{
    // helper function to give a positive value for a%b
    auto mod = [](int a, int b){ a %= b; return a &lt; 0 ? a + b : a; };

    std::unordered_map&lt;char, char&gt; map;
    {
        static const char alphabet[] = &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;;
        int const m = sizeof alphabet - 1; // subtract the final NUL
        for (int i = 0;  i &lt; m;  ++i) {
            map.insert(std::make_pair(alphabet[i], alphabet[mod(i+n,m)]));
        }
    }
    {
        static const char alphabet[] = &quot;abcdefghijklmnopqrstuvwxyz&quot;;
        int const m = sizeof alphabet - 1; // subtract the final NUL
        for (int i = 0; i &lt; m; i++) {
            map.insert(std::make_pair(alphabet[i], alphabet[mod(i+n,m)]));
        }
    }

    return map;
}

std::string Cipher::encrypt(std::string s) const
{
    std::transform(s.begin(), s.end(), s.begin(),
                   [=](char c){ auto it = map.find(c); return it == map.end() ? c : it-&gt;second; });
    return s;
}

I slightly modified the test program to allow it to accept command-line arguments (easier for test scripts):
#include &lt;cstdlib&gt;
#include &lt;iostream&gt;
int main(int argc, char **argv)
{
    int num;
    if (argc &gt; 1) {
        char* pos;
        num = std::strtol(argv[1], &amp;pos, 0);
        if (*pos || pos == argv[1]) {
            std::cerr &lt;&lt; &quot;Usage: &quot; &lt;&lt; argv[0] &lt;&lt; &quot; NUM WORD&quot; &lt;&lt; std::endl;
            return 1;
        }
    } else {
        std::cout &lt;&lt; &quot;Enter by how many numbers you want to shift alphabets: &quot;;
        std::cin &gt;&gt; num;
        std::cin.ignore();
    }
    Cipher cipher(num);
    Cipher decipher(-num);

    std::string str;
    if (argc &gt; 2) {
        str = argv[2];
    } else {
        std::cout &lt;&lt; &quot;Enter string: &quot;;
        std::getline(std::cin, str);
    }

    std::string res = cipher.encrypt(str);
    std::string decrypted = decipher.encrypt(res);
    std::cout &lt;&lt; &quot;Encrypted String: &quot;
              &lt;&lt; res &lt;&lt; '\n'
              &lt;&lt; &quot;Decrypted String: &quot;
              &lt;&lt; decrypted &lt;&lt; '\n';
}