-5

Hello i am new to c++ programming and i have write this code

#include <iostream>
#include <string>

using namespace std;

class Weapon
{
    string weaponName;
public:
    Weapon(string n)
    {
        weaponName=n;
        cout<<"Weapon created"<<endl;
    };

    ~Weapon()
    {
        cout<<"Weapon destroyed"<<endl;
    };

    //getter

    string getWeaponName()
    {
        return weaponName;
    };

    //setter

    string setWeaponName(string name2)
    {
        weaponName=name2;
    };


};

class Samurai 
{   
    string samuraiWeapon;
    string name;
    int age;
    int numberOfWins;
    int numberOfInjuries;
    int numberOfDuels;
 public:    
    Samurai(string t,int w,int i,int d,int a)
    {
        name=t;
        numberOfWins=w;
        numberOfInjuries=i;
        numberOfDuels=d;
        age=a;
        samuraiWeapon="no weapon";
        cout <<"Samurai ready for duel."<<endl;


    };

    ~Samurai()
    {
        cout<<"Samurai " << name <<" deleted "<<endl;
    };

    void  printSamuraiDescription()
    {
        cout<<"Samurai name: "<< name <<" Duels: "<<numberOfDuels<<" Wins: "<<numberOfWins<<"  Injuries: "<<numberOfInjuries<<endl;
    };

    void pickWeapon(Weapon &a)
    {
        if (age<18)
        {
            setSamuraiWeapon("Wooden Sword");
            cout<<samuraiWeapon<<endl;
        }
        else
        {
        setSamuraiWeapon(a.getWeaponName());
            cout<<samuraiWeapon<<endl;  
        }
    }

    //getters

    string getName()
    {
        return name;
    };

    string getSamuraiWeapon()
    {
        return samuraiWeapon;
    };

    int getnumberOfWins()
    {
        return numberOfWins;
    };

    int getnumberOfInjuries()
    {
        return numberOfInjuries;
    };

    int getnumberOfDuels()
    {
        return numberOfDuels;
    };

    int getAge()
    {
        return age;
    };

    //setters

    string setName(string a)
    {
         name=a;
    };

    string setSamuraiWeapon(string e)
    {
        samuraiWeapon=e;
    };

    int setnumberOfWins(int b)
    {
         numberOfWins=b;
    };

    int setnumberOfInjuries(int c)
    {
         numberOfInjuries=c;
    };

    int setnumberOfDuels(int d)
    {
         numberOfDuels=d;
    };

    int setAge(int f)
    {
        age=f;
    };

    //friend fuction
    friend void duel(Samurai &a, Samurai &b, bool winner);
    friend string duelForYoungSamurais(Samurai &a, Samurai &b);


};

string duelForYoungSamurais(Samurai &a, Samurai &b)
{
    if (a.age>18 || b.age>18)
    {
        cout<<"Invalid duel"<<endl;
    }

    if (a.samuraiWeapon!="Wooden Sword" || b.samuraiWeapon!="Wooden Sword")
    {
        cout<<"Duel postponed"<<endl;   
    }
    else
    {
        cout<<a.getName()<<" duels "<<b.getName()<<endl;
    }


}

void duel(Samurai &a, Samurai &b, bool winner)
{
    a.setnumberOfDuels(a.numberOfWins+1);
    b.setnumberOfDuels(b.numberOfWins+1);

    if (winner==true)
    {
        cout<<"Samurai a is winner "<<endl;
        a.setnumberOfWins(a.numberOfWins+1);
        b.setnumberOfInjuries(b.numberOfInjuries+1);
        if(a.numberOfWins>=10) cout<<"Samurai a is duelist"<<endl;
    }
    else
    {
        cout<<"Samurai b is winner "<<endl;
        b.setnumberOfWins(b.numberOfWins+1);
        a.setnumberOfInjuries(a.numberOfInjuries+1);
        if(b.numberOfWins>=10) cout<<"Samurai b is duelist"<<endl;  
    }


}

int main()
{
    Samurai a("Giorgos",9,0,0,18);
    Samurai b("Giannis",1,2,3,13);
    Weapon a1("Rock");
    a.pickWeapon(a1);
    b.pickWeapon(a1);
    duelForYoungSamurais(a,b);
    duel(a,b,true);
    a.printSamuraiDescription();
    b.printSamuraiDescription();


}

The programm compiles with no errors but when it starts and run it stops and in a few seconds end without do what i want and returns 3221225477 if i put in comments the part that have to do with the Weapon class and pickWeapon and duelForYoungSamurais fuctions my code runs just fine

  • in the university didnt learn us how to use the debugger and i can understand just by youtube videos – Konstantinos Moulakis Nov 14 '17 at 21:44
  • You do not have a `return 0;` statement at the end of `main`. How is main going to return anything without a return statement? – abelenky Nov 14 '17 at 21:45
  • 3
    non-void functions must return something. – user4581301 Nov 14 '17 at 21:45
  • 2
    @abelenky `main()` has an implicit `return 0;`. – juanchopanza Nov 14 '17 at 21:45
  • 2
    @abelenky In c++ `main` will implicitly return 0 if no return statement is encountered. It's a rule unique to `main`. – François Andrieux Nov 14 '17 at 21:45
  • 2
    *The programm compiles with no errors* -- But I bet you had warnings about returning nothing from a function that is supposed to return something, like your `setWeaponName` function. The code as-is invokes undefined behavior due to this issue. – PaulMcKenzie Nov 14 '17 at 21:46
  • @juanchopanza: while true, by pointing that out to a novice programmer, you are encouraging sloppy programming! If the desire is for a value to be returned, it should be explicitly done, and not rely on implicit behavior. Implicit behavior can come later when the program actually works. – abelenky Nov 14 '17 at 21:48
  • i put return 0; on main and a return to the other fuctions but i have still the same problem – Konstantinos Moulakis Nov 14 '17 at 21:49
  • 1
    @abelenky BS. There's nothing sloppy about omitting a return 0 from main(). If you actually write `return 0; ` I'd have to ask if you knew what you were doing. You are actually confusing a new comer by implying main needs an explicit return statement, and that their code is faulty for not having it. – juanchopanza Nov 14 '17 at 21:50
  • 1
    Why are you exposing both `getters` and `setters`? It's just strange and unnecessary, especially after saying "in the university didnt learn us how to use the debugger". – George Nov 14 '17 at 21:50
  • Once I clean up all of the setter functions that return nothing by replacing the return type with void, I get a tonne of errors. Good odds that all of the invalid functions confused the heck out of the compiler and produced a completely batsmurf program. – user4581301 Nov 14 '17 at 21:51
  • *put return 0; on main and a return to the other functions but i have still the same problem* -- Without changing what I mentioned, those problems will remain. – PaulMcKenzie Nov 14 '17 at 21:51
  • @George its a necessary requirement for the homework to put setters and getters – Konstantinos Moulakis Nov 14 '17 at 21:52
  • Just remember that there is almost never a reason for a setter function to have to return anything. – user4581301 Nov 14 '17 at 21:53
  • Whole bunch of [free functions](https://stackoverflow.com/questions/4861914/what-is-the-meaning-of-the-term-free-function-in-c) accessing private class members. You can't do that. – user4581301 Nov 14 '17 at 21:54
  • 1
    @KonstantinosMoulakis Well, it's silly, you should ask whoever set those requirements and see if they come back with something better than the usual "it's good practice" nonsense. – George Nov 14 '17 at 21:55
  • 1
    Recommendation. Don't write so much code at a time. Write a few lines, maybe a function, then compile. If you have enough to test, test it. But do not proceed until you have no compiler errors, no compiler errors and your testing finds no bugs. If you let any of these build up, they tend to interact with one another making it harder to sort out what's a real bug and what's an artifact of another bug. – user4581301 Nov 14 '17 at 21:56
  • 1
    What do you mean by "returns 3221225477"? The program prints that? That's the exit code? (I notice 3221225477 is 0xc0000005 - that might mean something.) – aschepler Nov 14 '17 at 21:58
  • here is a working code cpp.sh/46j35 the main and only problem was with your setters return type (should be `void`) - I have no idea why that even compiled – scope Nov 14 '17 at 21:59
  • 1
    Tactical point expanding on @George 's comment: If a variable has a getter and a setter and the setter does nothing to protect the variable from someone injecting a bad value, you might as well make the variable `public` and remove the setter and getter. Setters are all about the object protecting itself. If it's not protecting itself, the setter is just more code that can have a bug in it. – user4581301 Nov 14 '17 at 21:59
  • @user4581301 i didn't write all in once but khow i put the duelforyoungsamurais or the pickweapon parts in comment and i have the same problem – Konstantinos Moulakis Nov 14 '17 at 22:00
  • @aschepler I think the program blew up, and the cause more than likely is not addressing the compiler warnings about returning nothing from non-void functions. – PaulMcKenzie Nov 14 '17 at 22:00
  • @aschepler it prints Samurai ready for duel. Samurai ready for duel. Weapon created -------------------------------- Process exited after 3.735 seconds with return value 3221225477 Press any key to continue . . . – Konstantinos Moulakis Nov 14 '17 at 22:01
  • Somehow that mass of non-returning functions that should be returning successfully hides a raft of coding mistakes that ARE errors in gcc 4.8.5 and 4.9.2. No idea how. – user4581301 Nov 14 '17 at 22:02
  • @scope it didnt have any code on your comment attached – Konstantinos Moulakis Nov 14 '17 at 22:04
  • Here's something i didn't see earlier: `friend string duelForYoungSamurais(Samurai &a, Samurai &b);` but `duelForYoungSamurais` is defined as `void duelForYoungSamurais(Samurai &a, Samurai &b)`. Since the return types are different they aren't the same function, so the implementation of `duelForYoungSamurais` cannot access the private members. – user4581301 Nov 14 '17 at 22:05
  • @KonstantinosMoulakis The code contains no pointers, no arrays, no calls to `new`, etc. So the only thing I can see that would cause it to not work is (and this is the third time mentioning this) -- *your functions that are marked as returning `string` that fail to return a `string` are the most likely cause for the errors*. Playing around commenting out things is not going to fix that problem. Either make those functions `void`, or return a string. – PaulMcKenzie Nov 14 '17 at 22:05
  • @KonstantinosMoulakis there is this link there: http://cpp.sh/46j35 – scope Nov 14 '17 at 22:09

1 Answers1

2

Here, I corrected all setters with return type other than void and now it works:

#include <iostream>
#include <string>

using namespace std;

class Weapon
{
    string weaponName;
public:
    Weapon(string n)
    {
        weaponName=n;
        cout<<"Weapon created"<<endl;
    }

    ~Weapon()
    {
        cout<<"Weapon destroyed"<<endl;
    }

    //getter

    string getWeaponName()
    {
        return weaponName;
    }

    //setter

    void setWeaponName(string name2)
    {
        weaponName=name2;
    }


};

class Samurai 
{   
    string samuraiWeapon;
    string name;
    int age;
    int numberOfWins;
    int numberOfInjuries;
    int numberOfDuels;
    public:

    Samurai(string t,int w,int i,int d,int a)
    {
        name=t;
        numberOfWins=w;
        numberOfInjuries=i;
        numberOfDuels=d;
        age=a;
        samuraiWeapon="no weapon";
        cout <<"Samurai ready for duel."<<endl;


    };

    ~Samurai()
    {
        cout<<"Samurai " << name <<" deleted "<<endl;
    }

    void  printSamuraiDescription()
    {
        cout<<"Samurai name: "<< name <<" Duels: "<<numberOfDuels<<" Wins: "<<numberOfWins<<"  Injuries: "<<numberOfInjuries<<endl;
    }

    void pickWeapon(Weapon &a)
    {
        if (age<18)
        {
            setSamuraiWeapon("Wooden Sword");
            cout<<samuraiWeapon<<endl;
        }
        else
        {
        setSamuraiWeapon(a.getWeaponName());
            cout<<samuraiWeapon<<endl;  
        }
    }

    //getters

    string getName()
    {
        return name;
    }

    string getSamuraiWeapon()
    {
        return samuraiWeapon;
    }

    int getnumberOfWins()
    {
        return numberOfWins;
    }

    int getnumberOfInjuries()
    {
        return numberOfInjuries;
    }

    int getnumberOfDuels()
    {
        return numberOfDuels;
    }

    int getAge()
    {
        return age;
    }

    //setters

    void setName(string a)
    {
         name=a;
    }

    void setSamuraiWeapon(string e)
    {
        samuraiWeapon=e;
    }

    void setnumberOfWins(int b)
    {
         numberOfWins=b;
    }

    void setnumberOfInjuries(int c)
    {
         numberOfInjuries=c;
    }

    void setnumberOfDuels(int d)
    {
         numberOfDuels=d;
    }

    void setAge(int f)
    {
        age=f;
    }

    //friend fuction
    friend void duel(Samurai &a, Samurai &b, bool winner);
    friend void duelForYoungSamurais(Samurai &a, Samurai &b);


};

void duelForYoungSamurais(Samurai &a, Samurai &b)
{
    if (a.age>18 || b.age>18)
    {
        cout<<"Invalid duel"<<endl;
    }

    if (a.samuraiWeapon!="Wooden Sword" || b.samuraiWeapon!="Wooden Sword")
    {
        cout<<"Duel postponed"<<endl;   
    }
    else
    {
        cout<<a.getName()<<" duels "<<b.getName()<<endl;
    }


}

void duel(Samurai &a, Samurai &b, bool winner)
{
    a.setnumberOfDuels(a.numberOfWins+1);
    b.setnumberOfDuels(b.numberOfWins+1);

    if (winner==true)
    {
        cout<<"Samurai a is winner "<<endl;
        a.setnumberOfWins(a.numberOfWins+1);
        b.setnumberOfInjuries(b.numberOfInjuries+1);
        if(a.numberOfWins>=10) cout<<"Samurai a is duelist"<<endl;
    }
    else
    {
        cout<<"Samurai b is winner "<<endl;
        b.setnumberOfWins(b.numberOfWins+1);
        a.setnumberOfInjuries(a.numberOfInjuries+1);
        if(b.numberOfWins>=10) cout<<"Samurai b is duelist"<<endl;  
    }


}

int main()
{
    Samurai a("Giorgos",9,0,0,18);
    Samurai b("Giannis",1,2,3,13);
    Weapon a1("Rock");
    a.pickWeapon(a1);
    b.pickWeapon(a1);
    duelForYoungSamurais(a,b);
    duel(a,b,true);
    a.printSamuraiDescription();
    b.printSamuraiDescription();


}
scope
  • 1,967
  • 14
  • 15