As a clear copy of this question, I've written a Pokedex to teach myself the basics of classes, reading from files, using streams etc. I'd really appreciate some feedback on my approach as I'd like to get into good habits early on.I've got myself the Bjarne Stroustrup C++ book, so my learning should be a little more structured from now on, but this program is a good summary of everything I've learnt so far.I do also understand that comments should explain why and not how, but many of them are just there so I can make sure I understand what's going on.Pokedex.cpp#include stdafx.h#include <iostream>#include <string>#include <vector>#include <fstream>#include <sstream>#include <exception>//define global const which is where the Pokedex file is foundconst std::string POKEDEX_FILE_NAME = Data.txt;//define required Pokemon characteristics at the beginningtypedef int PDexNumber;typedef std::string Name;typedef double Weight;typedef double Height;typedef int PrevEvo;//define basic Pokemon typesenum class basicPokemonType{    Normal,    Fire,    Water,    Grass,    Fighting,    Flying,    Poison,    Electric,    Ground,    Psychic,    Rock,    Ice,    Bug,    Dragon,    Ghost,    Fairy,};basicPokemonType convertStringToType(std::string input){    std::stringstream sstr(input);    std::string typeString = ;    sstr >> typeString;    if (typeString == Normal)    {        return basicPokemonType::Normal;    }    else if (typeString == Fire)    {        return basicPokemonType::Fire;    }    else if (typeString == Water)    {        return basicPokemonType::Water;    }    else if (typeString == Grass)    {        return basicPokemonType::Grass;    }    else if (typeString == Fighting)    {        return basicPokemonType::Fighting;    }    else if (typeString == Flying)    {        return basicPokemonType::Flying;    }    else if (typeString == Poison)    {        return basicPokemonType::Poison;    }    else if (typeString == Electric)    {        return basicPokemonType::Electric;    }    else if (typeString == Ground)    {        return basicPokemonType::Ground;    }    else if (typeString == Psychic)    {        return basicPokemonType::Psychic;    }    else if (typeString == Rock)    {        return basicPokemonType::Rock;    }    else if (typeString == Ice)    {        return basicPokemonType::Ice;    }    else if (typeString == Bug)    {        return basicPokemonType::Bug;    }    else if (typeString == Dragon)    {        return basicPokemonType::Dragon;    }    else if (typeString == Ghost)    {        return basicPokemonType::Ghost;    }    else if (typeString == Fairy)    {        return basicPokemonType::Fairy;    }    else    {        return basicPokemonType::Normal;    }}std::string convertTypeToString(basicPokemonType input){    if (input == basicPokemonType::Normal)    {        return Normal;    }    else if (input == basicPokemonType::Fire)    {        return Fire;    }    else if (input == basicPokemonType::Water)    {        return Water;    }    else if (input == basicPokemonType::Grass)    {        return Grass;    }    else if (input == basicPokemonType::Fighting)    {        return Fighting;    }    else if (input == basicPokemonType::Flying)    {        return Flying;    }    else if (input == basicPokemonType::Poison)    {        return Poison;    }    else if (input == basicPokemonType::Electric)    {        return Electric;    }    else if (input == basicPokemonType::Ground)    {        return Ground;    }    else if (input == basicPokemonType::Psychic)    {        return Psychic;    }    else if (input == basicPokemonType::Rock)    {        return Rock;    }    else if (input == basicPokemonType::Ice)    {        return Ice;    }    else if (input == basicPokemonType::Bug)    {        return Bug;    }    else if (input == basicPokemonType::Dragon)    {        return Dragon;    }    else if (input == basicPokemonType::Ghost)    {        return Ghost;    }    else if (input == basicPokemonType::Fairy)    {        return Fairy;    }}//define Pokemon gendersenum class PokemonGender{    Male,    Female,    Both,    None,};PokemonGender convertStringToPokemonGender(std::string input){    std::stringstream sstr(input);    std::string gendString = ;    std::vector<std::string> tempVector;    while (sstr >> gendString)    {        tempVector.push_back(gendString);    }    if (tempVector.size() != 1)    {        return PokemonGender::Both;    }    else if (tempVector.at(0) == Male)    {        return PokemonGender::Male;    }    else if (tempVector.at(0) == Female)    {        return PokemonGender::Female;    }    else    {        return PokemonGender::None;    }}std::string convertPokemonGenderToString(PokemonGender gend){    if (gend == PokemonGender::Male)    {        return Male;    }    else if (gend == PokemonGender::Female)    {        return Female;    }    else if (gend == PokemonGender::Both)    {        return Male and Female;    }    else if (gend == PokemonGender::None)    {        return None;    }}//define Pokemon classclass Pokemon{private:    PDexNumber pdexNumber;    Name name;    basicPokemonType type;    Weight weight;    Height height;    PokemonGender gender;    PrevEvo prevEvo;public:    //getter and setter functions    PDexNumber getpdexNumber(void);    void setpdexNumber(int num);    Name getName(void);    void setName(std::string nm);    basicPokemonType getType(void);    void setType(basicPokemonType typ);    Weight getWeight(void);    void setWeight(double wgt);    Height getHeight(void);    void setHeight(double hgt);    PokemonGender getGender(void);    void setGender(PokemonGender gend);    PrevEvo getprevEvo(void);    void setPrevEvo(int num);    Pokemon(PDexNumber pdexNumber, Name name, basicPokemonType type, Weight weight, Height height,            PokemonGender gender, PrevEvo prevEvo);};//code getters and setters for class PokemonPDexNumber Pokemon::getpdexNumber (void){    return pdexNumber;}void Pokemon::setpdexNumber(int num){    pdexNumber = num;}Name Pokemon::getName(void){    return name;}void Pokemon::setName(std::string nm){    name = nm;}basicPokemonType Pokemon::getType(void){    return type;}void Pokemon::setType(basicPokemonType typ){    type = typ;}Weight Pokemon::getWeight(void){    return weight;}void Pokemon::setWeight(double wgt){    weight = wgt;}Height Pokemon::getHeight(void){    return height;}void Pokemon::setHeight(double hgt){    height = hgt;}PokemonGender Pokemon::getGender(void){    return gender;}void Pokemon::setGender(PokemonGender gend){    gender = gend;}PrevEvo Pokemon::getprevEvo(void){    return prevEvo;}void Pokemon::setPrevEvo(int num){    prevEvo = num;}Pokemon::Pokemon(PDexNumber pdexNumber, Name name, basicPokemonType type, Weight weight, Height height,    PokemonGender gender, PrevEvo prevEvo){    setpdexNumber(pdexNumber);    setName(name);    setType(type);    setWeight(weight);    setHeight(height);    setGender(gender);    setPrevEvo(prevEvo);}std::vector<Pokemon> readFileIntoPokemonVector (std::string filename){    std::ifstream readFile(filename);    std::vector<Pokemon> tempPokemon;    std::string tempPDexNumber = ;    std::string tempName = ;    std::string tempType = ;    std::string tempWeight = ;    std::string tempHeight = ;    std::string tempGender = ;    std::string tempPrevEvo = ;    std::getline(readFile, tempPDexNumber, ',');    std::getline(readFile, tempName, ',');    std::getline(readFile, tempType, ',');    std::getline(readFile, tempWeight, ',');    std::getline(readFile, tempHeight, ',');    std::getline(readFile, tempGender, ',');    std::getline(readFile, tempPrevEvo, ',');    while (readFile)    {        tempPokemon.push_back(Pokemon(std::stoi(tempPDexNumber), tempName, convertStringToType(tempType),            std::stod(tempWeight), std::stod(tempHeight), convertStringToPokemonGender(tempGender), std::stoi(tempPrevEvo)));        std::getline(readFile, tempPDexNumber, ',');        std::getline(readFile, tempName, ',');        std::getline(readFile, tempType, ',');        std::getline(readFile, tempWeight, ',');        std::getline(readFile, tempHeight, ',');        std::getline(readFile, tempGender, ',');        std::getline(readFile, tempPrevEvo, ',');    }    return tempPokemon;} Name returnNextEvoName(PDexNumber origPokemonNum, std::vector<Pokemon> pokemonVector){    //the next evolution is never more than 3 pokemon away    //(most are two, but Eevee has three)    //therefore, all we need to do is check the next three pokemon to see if their prevEvo    //is equal to the pdex number of the one we are looking at    for (size_t pdexOffset = 1; pdexOffset < 4; pdexOffset++)    {        try        {            if (pokemonVector.at(origPokemonNum + pdexOffset).getprevEvo() == origPokemonNum + 1)            {                return pokemonVector.at(origPokemonNum + pdexOffset).getName();            }        }        catch (...)        {            return No further evolutions;        }    }    return No further evolutions;} Name returnPrevEvoName(PDexNumber origPokemonNum, std::vector<Pokemon> pokemonVector) {     if (pokemonVector.at(origPokemonNum).getprevEvo() == 0)     {         return No previous evolution;     }     else     {         return pokemonVector.at(pokemonVector.at(origPokemonNum).getprevEvo() - 1).getName();     } }void PrintPokemon(int pokedexNo, std::vector<Pokemon> pokemonVector){    int numOfCharactersInName = 0;    if (pokemonVector.empty() == true)    {        std::cout << Vector is empty.;    }    numOfCharactersInName = pokemonVector.at(pokedexNo).getName().length();    std::string titleUnderline=-;    for (int i = 1; i < numOfCharactersInName; i++)    {        titleUnderline = titleUnderline + -;    }    std::cout << pokemonVector.at(pokedexNo).getName() << \n;    std::cout << titleUnderline << \n;    std::cout << Pokedex number:  << pokedexNo + 1 << \n;    std::cout << Type:  << convertTypeToString(pokemonVector.at(pokedexNo).getType()) << \n;    std::cout << Height:  << pokemonVector.at(pokedexNo).getHeight() << \n;    std::cout << Weight:  << pokemonVector.at(pokedexNo).getWeight() << \n;    std::cout << Gender:  << convertPokemonGenderToString(pokemonVector.at(pokedexNo).getGender()) << \n;    std::cout << Previous Evolution:  << returnPrevEvoName(pokedexNo, pokemonVector) << \n;    std::cout << Next Evolution:  << returnNextEvoName(pokedexNo, pokemonVector) << \n;}//function guarantees that we get a long from user inputlong getLongFromUser(std::string strPrompt, long minNum, long maxNum) {    long result = 0;    while (true || (result >= minNum && result <= maxNum))    {        std::string strinput = ;        //use getline to avoid errors with inputs        std::cout << strPrompt;        std::getline(std::cin, strinput);        // this line defines a stringstream called 'mystream' and gives it the value of strinput        std::stringstream myStream(strinput);        //this line looks for result (i.e. a signed long) and stores it. If it can't, it returns false        if (myStream >> result) {            if (result < minNum || result > maxNum)            {                std::cout << Please enter a number between  << minNum <<  and  << maxNum << .\n;            }            else            {                break;            }        }        else        {            std::cout << That's not a number. Please enter a number.\n;        }    }    return result;}int main(){    //load Pokedex    std::vector<Pokemon> Pokedex = readFileIntoPokemonVector(POKEDEX_FILE_NAME);    std::cout << Welcome to Pokedex!\n;    long choosePokemon = 0;    do    {        choosePokemon = getLongFromUser(Please enter the number of the Pokemon you want to look up, or enter 0 to exit.\n, 0, 123);        if (choosePokemon != 0)        {            PrintPokemon(choosePokemon - 1, Pokedex); //offset -1 because vectors start at 0        }    } while (choosePokemon != 0);       return 0;}Data.txt1, Bulbasaur, Grass and Poison, 15.2, 28, Male and Female, 0,2, Ivysaur, Grass and Poison, 28.7, 39, Male and Female, 1,3, Venusaur, Grass and Poison, 220.5, 79, Male and Female,2,4, Charmander, Fire, 18.7, 24, Male and Female, 0,5, Charmeleon, Fire, 41.9, 44, Male and Female, 4,6, Charizard, Fire and Flying, 199.5, 67, Male and Female, 5,7, Squirtle, Water, 19.8, 20, Male and Female, 0,8, Wartortle, Water, 49.6, 39, Male and Female, 7,9, Blastoise, Water, 188.5, 63, Male and Female, 8,10, Caterpie, Bug, 6.4, 12, Male and Female, 0,11, Metapod, Bug, 21.8, 28, Male and Female, 10,12, Butterfree, Bug and Flying, 70.5, 43, Male and Female, 11,13, Weedle, Bug and Poison, 7.1, 12, Male and Female, 0,14, Kakuna, Bug and Poison, 22, 24, Male and Female, 13,15, Beedrill, Bug and Poison, 65, 39, Male and Female, 14,16, Pidgey, Normal and Flying, 4, 12, Male and Female, 0,17, Pidgeotto, Normal and Flying, 66.1, 43, Male and Female, 16,18, Pidgeot, Normal and Flying, 87.1, 59, Male and Female, 17,19, Rattata, Normal, 7.7, 12, Male and Female, 0,20, Raticate, Normal, 40.8, 28, Male and Female, 19,21, Spearow, Normal and Flying, 4.4, 12, Male and Female, 0,22, Fearow, Normal and Flying, 83.8, 47, Male and Female, 21,23, Ekans, Poison, 15.2, 79, Male and Female, 0,24, Arbok, Poison, 143.3, 138, Male and Female, 23,25, Pikachu, Electric, 13.2, 16, Male and Female, 0,26, Raichu, Electric, 66.1, 31, Male and Female, 25,27, Sandshrew, Ground, 26.5, 24, Male and Female, 0,28, Sandslash, Ground, 65, 39, Male and Female, 27,29, Nidoran female, Poison, 15.4, 16, Female, 0,30, Nidorina, Poison, 44.1, 31, Female, 29,31, Nidoqueen, Poison and Ground, 132.3, 51, Female, 30,32, Nidoran Male, Poison, 19.8, 20, Male, 0,33, Nidorino, Poison, 43, 35, Male, 32,34, Nidoking, Poison and Ground, 136.7, 55, Male, 33,35, Clefairy, Fairy, 16.5, 24, Male and Female, 0,36, Clefable, Fairy, 88.2, 51, Male and Female, 35,37, Vulpix, Fire, 21.8, 24, Male and Female, 0,38, Ninetales, Fire, 43.9, 43, Male and Female, 37,39, Jigglypuff, Normal and Fairy, 12.1, 20, Male and Female, 0,40, Wigglytuff, Normal and Fairy, 26.5, 39, Male and Female, 39,41, Zubat, Poison and Flying, 16.5, 31, Male and Female, 0,42, Golbat, Poison and Flying, 121.3, 63, Male and Female, 41,43, Oddish, Grass and Poison, 11.9, 20, Male and Female, 0,44, Gloom, Grass and Poison, 19, 31, Male and Female, 43,45, Vileplume, Grass and Poison, 41, 47, Male and Female, 44,46, Paras, Bug and Grass, 11.9, 12, Male and Female, 0,47, Parasect, Bug and Grass, 65, 39, Male and Female, 46,48, Venonat, Bug and Poison, 66.1, 39, Male and Female, 0,49, Venomoth, Bug and Poison, 27.6, 59, Male and Female, 48,50, Diglett, Ground, 1.8, 8, Male and Female, 0,51, Dugtrio, Ground, 73.4, 28, Male and Female,52,52, Meowth, Normal, 9.3, 16, Male and Female, 0,53, Persian, Normal, 70.5, 39, Male and Female, 52,54, Psyduck, Water, 43.2, 31, Male and Female, 0,55, Golduck, Water, 168.9, 67, Male and Female, 54,56, Mankey, Fighting, 61.7, 20, Male and Female, 0,57, Primeape, Fighting, 70.5, 39, Male and Female, 56,58, Growlithe, Fire, 41.9, 28, Male and Female, 0,59, Arcanine, Fire, 341.7, 63, Male and Female, 58,60, Poliwag, Water, 27.3, 24, Male and Female, 0,61, Poliwhirl, Water, 44.1, 39, Male and Female, 60,62, Poliwrath, Water and Fighting, 119, 51, Male and Female, 61,63, Abra, Psychic, 43, 35, Male and Female, 0,64, Kadabra, Psychic, 124.6, 51, Male and Female, 63,65, Alakazam, Psychic, 105.8, 59, Male and Female, 64,66, Machop, Fighting, 43, 31, Male and Female, 0,67, Machoke, Fighting, 155.4, 59, Male and Female,66,68, Machamp, Fighting, 286.6, 63, Male and Female, 67,69, Bellsprout, Grass and Poison, 8.8, 28, Male and Female, 0,70, Weepinbell, Grass and Poison, 14.1, 39, Male and Female, 69,71, Victreebel, Grass and Poison, 34.2, 67, Male and Female, 70,72, Tentacool, Water and Poison, 100.3, 35, Male and Female, 0,73, Tentacruel, Water and Poison, 121.3, 63, Male and Female, 72,74, Geodude, Rock and Ground, 44.1, 16, Male and Female, 0,75, Graveler, Rock and Ground, 231.5, 39, Male and Female, 74,76, Golem, Rock and Ground, 661.4, 31, Male and Female, 75,77, Ponyta, Fire, 66.1, 39, Male and Female, 0,78, Rapidash, Fire, 209.4, 67, Male and Female, 77,79, Slowpoke, Water and Psychic, 79.4, 47, Male and Female, 0,80, Slowbro, Water and Psychic, 173.1, 63, Male and Female, 79,81, Magnemite, Electric and Steel, 13.2, 12, None, 0,82, Magneton, Electric and Steel, 132.3, 39, None, 81,83, Farfetch'd, Normal and Flying, 33.1, 31, Male and Female, 0,84, Doduo, Normal and Flying, 86.4, 45, Male and Female, 0,85, Dodrio, Normal and Flying, 187.8, 71, Male and Female, 84,86, Seel, Water, 198.4, 43, Male and Female, 0,87, Dewgong, Water and Ice, 264.6, 67, Male and Female, 86,88, Grimer, Poison, 66.1, 35, Male and Female, 0,89, Muk, Poison, 66.1, 47, Male and Female, 88,90, Shellder, Water, 8.8, 12, Male and Female, 0,91, Cloyster, Water and Ice, 292.1, 59, Male and Female, 90,92, Gastly, Ghost and Poison, 0.2, 51, Male and Female, 0,93, Haunter, Ghost and Poison, 0.2, 63, Male and Female, 92,94, Gengar, Ghost and Poison, 89.3, 59, Male and Female, 93,95, Onix, Rock and Ground, 463, 346, Male and Female, 0,96, Drowzee, Psychic, 71.4, 39, Male and Female, 0,97, Hypno, Psychic, 166.7, 63, Male and Female, 96,98, Krabby, Water, 14.3, 16, Male and Female, 0,99, Kingler, Water, 132.3, 51, Male and Female, 98,100, Voltorb, Electric, 22.9, 20, None, 0,101, Electrode, Electric, 146.8, 47, Male and Female, 100,102, Exeggcute, Grass and Psychic, 5.5, 16, Male and Female, 0,103, Exeggutor, Grass and Psychic, 264.6, 79, Male and Female,102,104, Cubone, Ground, 14.3, 16, Male and Female, 0,105, Marowak, Ground, 99.2, 39, Male and Female, 104,106, Hitmonlee, Fighting, 109.8, 59, Male, 0,107, Hitmonchan, Fighting, 110.7, 55, Male, 0,108, Lickitung, Normal, 144.4, 47, Male and Female, 0,109, Koffing, Poison, 2.2, 24, Male and Female, 0,110, Weezing, Poison, 20.9, 47, Male and Female, 109,111, Rhyhorn, Ground and Rock, 253.5, 39, Male and Female,0,112, Rhydon, Ground and Rock, 264.6, 75, Male and Female, 111,113, Chansey, Normal, 76.3, 43, Female, 0,114, Tangela, Grass, 77.2, 39, Male and Female, 0,115, Kangaskhan, Normal, 176.4, 87, Female, 0,116, Horsea, Water, 17.6, 16, Male and Gender, 0,117, Seadra, Water, 55.1, 47, Male and Female, 116,118, Goldeen, Water, 33.1, 24, Male and Female, 0,119, Seaking, Water, 86, 51, Male and Female, 118,120, Staryu, Water, 76.1, 31, None, 0,121, Starmie, Water and Psychic, 176.4, 43, None, 120,122, Mr. Mime, Fairy and Psychic, 120, 51, Male and Female, 0,123, Scyther, Bug and Flying, 123.5, 59, Male and Female, 0,
Beginner Pokedex in C++
c++;beginner;pokemon
I see a number of things that may help you improve your code.Don't obfuscate standard typesThe current code includes these lines:typedef int PDexNumber;typedef std::string Name;typedef double Weight;typedef double Height;typedef int PrevEvo;Then it uses these like this:PDexNumber pdexNumber;Name name;basicPokemonType type;Weight weight;Height height;PokemonGender gender;PrevEvo prevEvo;This is not only unhelpful but counterproductive.  Experienced programmers know what a double is, but would have to look up what a Weight is.  That's bad.  Instead, we want programmers to be able to read the code without a lot of effort, so just omit these typedefs.C++ isn't JavaDon't create setters and getters for every data member.  C++ is not Java and C++ programmers simply don't do that.  The reason is that if you need to have unfettered read and write access to every data member, simply declare them all to be public.  However, in most cases, this isn't really needed.  Be selective about revealing the internals of your class.  Use C++ idiomsInstead of defining a standalone PrintPokemon in the way you've done, I'd recommend instead to define a overload for ostream &operator<< for the Pokemon class.  Here's one way to write it.  First, within the class declare a friend function like so:friend std::ostream &operator<<(std::ostream &out, const Pokemon &p);Then outside the class declaration, we define the function:std::ostream &operator<<(std::ostream &out, const Pokemon &p) {    return out << p.name << '\n'            << std::string(p.name.size(), '-')             << \nPokedex number:  << p.pdexNumber             << \nType:  << convertTypeToString(p.type)            << \nHeight:  << p.height            << \nWeight:  << p.weight            << \nGender:  << convertPokemonGenderToString(p.gender);}Note that this doesn't yet print the Previous Evolution and Next Evolution, but I'll address that in a later suggestion.Use modern constructorsThe code you've got already requires C++11, so there's no reason not to use modern style constructors.  Specifically, write the constructor like this:Pokemon::Pokemon(int pdexNumber, std::string name, basicPokemonType type, double weight,     double height, PokemonGender gender, int prevEvo):    pdexNumber(pdexNumber),    name(name),    type(type),    weight(weight),    height(height),    gender(gender),    prevEvo(prevEvo){}This eliminates the need for all of those ugly and repetitive setters.Encapsulate definitions within classes where logicalThere is probably little use for a PokemonGender without an associated Pokemon, so I'd suggest putting that enum within the Pokemon class.  Even better, in my view, would be to rethink how it will be used.  Ultimately, there are fixed number of categories and associated strings.  I'd suggest that perhaps instead of an enum, that a std::array of std::string or const char * might be more appropriate.  Here's how I would do it.  First, I'd change the type of gender to unsigned within the private data members of the Pokemon class.  Then I'd declare the following items within that class:static constexpr std::array<const char *, 4> genders{Male, Female, Male and Female, None};static unsigned stringToGender(std::string &tempGender);   const char *getGender() const;Then outside the class, the following definitions:constexpr std::array<const char *, 4> Pokemon::genders;const char *Pokemon::getGender() const {    return genders[gender];}unsigned Pokemon::stringToGender(std::string &tempGender) {    unsigned retval{0};    for (const auto &label : genders) {        if (label == tempGender) {            break;        }        ++retval;    }    return retval == genders.size() ? genders.size()-1 : retval;}You can do a similar thing  with the Pokemon types (with a bit more work, since each can have multiple types) and the resulting code is both shorter and easier to read.Avoid magic numbersInstead of hardcoding 123 as the upper limit, it would be better to use Pokedex.size() so that the actual vector size as read from the file is being used rather than some hardcoded number.Rethink your classesThere are really two kinds of objects in the existing program.  First is the Pokemon and second is a collection of them.  Because the relationships among them are important, I'd suggest that either there could be a PokemonCollection object or that there should be preEvo and nextEvo pointers within each Pokemon class.  Either is a valid approach, but I suspect that having a PokemonCollection object would be handier.  It would be convenient, for example, to see the hierarchy of a particular Pokemon evolution without having to guess at index numbers.  Either way, the hierarchy should be determined once as the input is read and then simply used, rather than having to recalculate it each time it's needed.Omit return 0When a C or C++ program reaches the end of main the compiler will automatically generate code to return 0, so there is no need to put return 0; explicitly at the end of main.  Note: when I make this suggestion, it's almost invariably followed by one of two kinds of comments:  I didn't know that. or That's bad advice!  My rationale is that it's safe and useful to rely on compiler behavior explicitly supported by the standard.  For C, since C99; see ISO/IEC 9899:1999 section 5.1.2.2.3:[...] a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0.For C++, since the first standard in 1998; see ISO/IEC 14882:1998 section 3.6.1:If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;All versions of both standards since then (C99 and C++98) have maintained the same idea.  We rely on automatically generated member functions in C++, and few people write explicit return; statements at the end of a void function.  Reasons against omitting seem to boil down to it looks weird.  If, like me, you're curious about the rationale for the change to the C standard read this question.  Also note that in the early 1990s this was considered sloppy practice because it was undefined behavior (although widely supported) at the time.  So I advocate omitting it; others disagree (often vehemently!)  In any case, if you encounter code that omits it, you'll know that it's explicitly supported by the standard and you'll know what it means.