new to the try/catch thing and need to use it for a program. For some reason though my program crashes when it catches the obj. The sample program I wrote just reads in a number and then tests to see if its below 10 or above 20. The point is to use two user defined classes to throw and catch. The above 20 obj gets thrown and catches just fine. But the below 10, if its thrown will crash the program. Why is this? here is my code
#include <iostream>
#include <cstdlib>
using namespace std;
class above20
{
public:
above20()
{
msg = "Number is above 20.";
};
string getmsg()
{
cout<<msg<<endl;
};
private:
string msg;
};
class below10
{
public:
below10()
{
msg = "Number is below 10";
};
string getmsg()
{
cout<<msg<<endl;
};
private:
string msg;
};
int main ()
{
int num;
try
{
cout<<"Enter Number between 10 and 20:"<<endl;
cin >> num;
if (num > 20)
{
throw above20 ();
}
}
catch (above20 obj)
{
obj.getmsg();
}
try
{
if (num < 10)
{
throw below10 ();
}
}
catch (below10 obj)
{
obj.getmsg();
}
system ("pause");
return (0);
}
Are you sure this compiles? Did you omit something in your copy paste? The getmsg() methods don't return anything.
---edit ---
Try this:
void getmsg()
{
cout<<msg<<endl;
};
You have a lot of poor syntax in your code. The error you get is because you declare getMsg with a return value and do not return (UB - you are lucky it even compiles!).
To fix all of your issues: http://ideone.com/1qGAuR
You have a few errors in your code like having a function that doesn’t return anything despite saying that it should in the signature:
string getmsg()
{
cout<<msg<<endl;
};
should really be:
void getmsg()
{
cout<<msg<<endl;
};
or
string getmsg()
{
return string(msg);
};
Putting aside those bugs for a second, from a design point of view inheriting from one exception base class is cleaner. I would usually inherit from std::runtime_error but you could define your own if you wanted. For example :
#include <iostream>
#include <cstdlib>
using namespace std;
class above_below_exception
{
public:
virtual string getmsg() =0;
};
class above20 : public above_below_exception
{
public:
above20()
{
msg = "Number is above 20.";
};
string getmsg()
{
return string(msg);
};
private:
string msg;
};
class below10 : public above_below_exception
{
public:
below10()
{
msg = "Number is below 10";
};
string getmsg()
{
return string(msg);
};
private:
string msg;
};
int main ()
{
int num;
try
{
cout<<"Enter Number between 10 and 20:"<<endl;
cin >> num;
if (num > 20)
{
throw above20();
}
if (num < 10)
{
throw below10();
}
}
catch (above_below_exception& obj)
{
cout << obj.getmsg();
}
return (0);
}
A potential fix for your code:
#include <iostream>
#include <cstdlib>
using namespace std;
class above20 : public std::exception
{
public:
above20()
{
msg = "Number is above 20.";
}
virtual ~above20 () throw ()
{
}
string getmsg ()
{
cout << msg << endl;
return msg;
}
private:
string msg;
};
class below10 : public std::exception
{
public:
below10()
{
msg = "Number is below 10";
}
virtual ~below10 () throw ()
{
}
string getmsg()
{
cout << msg << endl;
return msg;
}
private:
string msg;
};
int main ()
{
int num;
try
{
cout<<"Enter Number between 10 and 20:"<<endl;
cin >> num;
if (num > 20)
{
throw above20 ();
}
}
catch (above20 &obj)
{
cout << obj. getmsg () << endl;
}
try
{
if (num < 10)
{
throw below10 ();
}
}
catch (below10 obj)
{
obj.getmsg();
}
system ("pause");
return (0);
}
Related
In my function 'func' i want to create an object Menu who returns a breakfast with lemon and coffee. 'func' return a list of menu
When I try to display the menu for a breakfast that contains only lemon or only coffee it is displayed correctly. For example:
c.push_back(make_unique<Breakfast>("eggs", 10));
but when i try to display a menu that also contains lemon and coffee it shows me error in main
this is the program:
#include <iostream>
#include <vector>
using namespace std;
class Menu {
private:
int price;
public:
Menu(int p = 0) : price{ p } {}
virtual string description() = 0;
virtual int getPrice() {
return price;
}
virtual ~Menu() {}
};
class WithLemon : public Menu {
private:
Menu* meniu;
public:
WithLemon(Menu* n) :
meniu{ n } {}
string description() override {
return meniu->description() + " with lemon ";
}
int getPrice() override {
return meniu->getPrice() + 4;
}
};
class WithCoffee : public Menu {
private:
Menu* meniu;
public:
WithCoffee(Menu* n) :
meniu{ n } {
}
string description() override {
return meniu->description() + " with coffee ";
}
int getPrice() override {
return meniu->getPrice() + 5;
}
};
class Breakfast : public Menu {
private:
string name;
public:
Breakfast(string n, int p) :
name{ n }, Menu{ p } {
}
string description() override {
return name;
}
};
std::vector<std::unique_ptr<Menu>> func(void)
{
std::vector <std::unique_ptr<Menu> > c;
Breakfast a{ "breakfast eggs", 10 };
WithCoffee breakfast_with_coffee{ &a };
Menu* breakfast_with_coffee_and_lemon = new WithLemon{ &breakfast_with_coffee };
//cout << breakfast_with_coffee_and_lemon->description() << " " << breakfast_with_coffee_and_lemon->getPrice();// print ----> breakfast eggs with coffee with lemon 19
c.push_back(make_unique<WithLemon>(&breakfast_with_coffee));
return c;
}
int main() {
std::vector < std::unique_ptr<Menu> > lista = func();
for (int i = 0; i < lista.size(); i++) {
cout << lista[i]->description() << " " << lista[i]->getPrice() << endl; //error read memory access
}
return 0;
}
You can't take a pointer to automatic memory, store it in a smart pointer and leave the function. After you leave the function the automatic memory is freed and the smart pointer contains a dangling pointer. The simplest way to avoid this problem and other problems with memory leaks is to use smart pointers for all variables:
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class Menu {
private:
int price;
public:
Menu(int p = 0) : price{ p } {}
virtual std::string description() = 0;
virtual int getPrice() {
return price;
}
virtual ~Menu() = default;
};
class WithLemon : public Menu {
private:
std::unique_ptr<Menu> meniu;
public:
WithLemon(Menu* n) : meniu{ n } {}
std::string description() override {
return meniu->description() + " with lemon ";
}
int getPrice() override {
return meniu->getPrice() + 4;
}
};
class WithCoffee : public Menu {
private:
std::unique_ptr<Menu> meniu;
public:
WithCoffee(Menu* n) :
meniu{ n } {
}
std::string description() override {
return meniu->description() + " with coffee ";
}
int getPrice() override {
return meniu->getPrice() + 5;
}
};
class Breakfast : public Menu {
private:
std::string name;
public:
Breakfast(std::string n, int p) : Menu{ p }, name{ n } {}
std::string description() override {
return name;
}
};
std::vector<std::unique_ptr<Menu>> func(void) {
std::vector <std::unique_ptr<Menu> > c;
auto a = std::make_unique<Breakfast>("breakfast eggs", 10);
auto breakfast_with_coffee = std::make_unique<WithCoffee>(a.release());
//Menu* breakfast_with_coffee_and_lemon = new WithLemon{ breakfast_with_coffee };
//std::cout << breakfast_with_coffee_and_lemon->description() << " " << breakfast_with_coffee_and_lemon->getPrice();// print ----> breakfast eggs with coffee with lemon 19
c.push_back(std::make_unique<WithLemon>(breakfast_with_coffee.release()));
return c;
}
int main() {
std::vector < std::unique_ptr<Menu> > lista = func();
for (const auto &i : lista) {
std::cout << i->description() << " " << i->getPrice() << std::endl; //error read memory access
}
return 0;
}
Avoid raw new and delete. Avoid pointers to automatic memory.
I have written a code like bill payment. Code is working fine but there are many warnings in my code which I want to remove. One of the most frequent warning is deprecated conversion from string constant to 'char* . I have tried many things and some of the warnings are gone but not all. Please anybody point out at my mistakes??
P.S: I have already tried replacing char* to const char* , but then I am not able to exchange or swap values and it was causing error. Any other solution??
Below is the code
#include<iostream>
#include<string.h>
using namespace std;
class item
{
private:
int barcode;
char* item_name;
public:
item (int num=0, char* name="NULL") : barcode(num)
{
item_name=new char[strlen(name)+1];
strcpy(item_name,name);
}
void setbarcode(int num)
{
barcode=num;
}
int getbarcode()
{
return barcode;
}
void scanner()
{
int num;
cin>>num;
setbarcode(num);
}
void printer()
{
cout <<"\nBarcode"<<"\t\t"<<"Item Name"<<"\t\t"<<"Price"<<endl;
cout <<barcode<<"\t\t"<<item_name<<"\t\t\t";
}
~item()
{
delete[]item_name;
}
};
class packedfood : public item
{
private :
int price_per_piece;
public :
packedfood(int a=0, int num=0, char* name = "NULL") : price_per_piece(a),item(num,name)
{
}
void setprice(int num)
{
price_per_piece=num;
}
int getprice()
{
return price_per_piece;
}
void scanner()
{
item::scanner();
}
void printer()
{
item::printer();
cout<<getprice()<<" Per Piece";
}
~packedfood()
{
}
};
class freshfood: public item
{
private:
int price_per_rupee;
float weight;
public:
freshfood(float b=0, int a=0,int num=0,char* name="NULL") : weight(b),price_per_rupee(a),item(num,name)
{
}
void setweight(float b)
{
weight=b;
}
int getweight()
{
return weight*50;
}
void printer()
{
item::printer();
cout<<getweight()<<" Per Rupee"<<endl<<endl;
}
void scanner()
{
item::scanner();
}
~freshfood()
{
}
};
int main()
{
item x(389,"Anything");
item y;
packedfood m(10,118,"Chocolate");
packedfood n;
freshfood r(20.9,93,357,"Fruits");
freshfood s;
cout <<"\n\n Enter the Barcode for Packed food : ";
m.scanner();
m.printer();
cout <<"\n\n Enter the Barcode for Fresh food : ";
r.scanner();
r.printer();
system("PAUSE");
return 0;
}
I have a problem in which I have to return the name of a winner in a fight between two fighters.
The class for fighter is as follows:
class Fighter
{
private:
std::string name;
int health;
int damagePerAttack;
public:
Fighter(std::string name, int health, int damagePerAttack)
{
this->name = name;
this->health = health;
this->damagePerAttack = damagePerAttack;
}
~Fighter() { };
std::string getName()
{
return name;
}
int getHealth()
{
return health;
}
int getDamagePerAttack()
{
return damagePerAttack;
}
void setHealth(int value)
{
health = value;
}
};
I wrote a function that should return the name of the winner.
std::string declareWinner(Fighter* fighter1, Fighter* fighter2,
std::string firstAttacker)
{
// Your code goes here. Have fun!
if(firstAttacker==fighter1->getName())
{
while(fighter1->getHealth()!=0&&fighter2->getHealth()!=0)
{
fighter2->setHealth(fighter2->getHealth()-fighter1->getDamagePerAttack());
if(fighter2->getHealth()<=0)
{
return fighter1->getName();
}
fighter1->setHealth(fighter1->getHealth()-fighter2->getDamagePerAttack());
if(fighter1->getHealth()<=0)
{
return fighter2->getName();
}
}
}
else if(firstAttacker==fighter2->getName())
{
while(fighter1->getHealth()!=0&&fighter2->getHealth()!=0)
{
fighter1->setHealth(fighter1->getHealth()-fighter2->getDamagePerAttack());
if(fighter1->getHealth()<=0)
{
return fighter2->getName();
}
fighter2->setHealth(fighter2->getHealth()-fighter1->getDamagePerAttack());
if(fighter2->getHealth()<=0)
{
return fighter1->getName();
}
}
}
}
This satisfies all my needs, but it throws SIGILL signal, and i do not know what i did wrong. How should I deal with it?
In some conditions, it is possible that function runs to the end and exits without returning a value, that corrupts stack and can lead to SIGILL. As a safe measure you can, for example, add return statement to the end of function.
std::string declareWinner(Fighter* fighter1, Fighter* fighter2,
std::string firstAttacker)
{
// Your code goes here. Have fun!
if(firstAttacker==fighter1->getName())
{
while(fighter1->getHealth()!=0&&fighter2->getHealth()!=0)
{
fighter2->setHealth(fighter2->getHealth()-fighter1->getDamagePerAttack());
if(fighter2->getHealth()<=0)
{
return fighter1->getName();
}
fighter1->setHealth(fighter1->getHealth()-fighter2->getDamagePerAttack());
if(fighter1->getHealth()<=0)
{
return fighter2->getName();
}
}
}
else if(firstAttacker==fighter2->getName())
{
while(fighter1->getHealth()!=0&&fighter2->getHealth()!=0)
{
fighter1->setHealth(fighter1->getHealth()-fighter2->getDamagePerAttack());
if(fighter1->getHealth()<=0)
{
return fighter2->getName();
}
fighter2->setHealth(fighter2->getHealth()-fighter1->getDamagePerAttack());
if(fighter2->getHealth()<=0)
{
return fighter1->getName();
}
}
}
return "No winner"; <= Add before exiting function
}
I also noticed there's a redundancy and possible logical errors in code.
I would rewrite it like this (without changing function signature):
std::string declareWinner(Fighter* fighter1, Fighter* fighter2,
std::string firstAttacker)
{
Fighter *first;
Fighter *second;
if(firstAttacker == fighter1->getName()) {
first = fighter2;
second = fighter1;
} else if (firstAttacker == fighter2->getName()) {
first = fighter1;
second = fighter2;
} else {
// Bad call parameters
return "Bad call"; // Throw exception maybe?
}
// Simulating fighting
do {
std::swap(second,first);
second->setHealth(second->getHealth() - first->getDamagePerAttack());
} while (second->getHealth() > 0);
return first->getName();
}
I've been working with exception handling for a long while today. I've figured out to get it to work if it's in a void function, but how do I handle functions that have to return a value. The last 3 lines in main are where the "issue" happens. I found this link earlier to help me get this far, but my exception handling has to all be contained inside the class structure, so I can't have try/throw/catch in main. I'd like to understand what's going on. [1]: What type of exception should I throw?
Thanks in advance.
#include <iostream>
#include <exception>
class out_of_range : public std::exception
{
private:
std::string msg;
public:
out_of_range(const std::string msg) : msg(msg){};
~out_of_range(){};
virtual const char * what()
{
return msg.c_str();
}
};
class divide
{
private:
int a;
int * _ptr;
public:
divide(int r): a(r), _ptr(new int[a]) {};
~divide(){ delete[] _ptr; };
int get(int index) const
{
try
{
if (index < 0 || index >= a)
throw out_of_range("Err");
else
return _ptr[index];
}
catch (out_of_range & msg)
{
std::cout << msg.what() << std::endl;
}
}
int &get(int index)
{
try
{
if (index < 0 || index >= a)
throw out_of_range("Err");
else
return _ptr[index];
}
catch (out_of_range & msg)
{
std::cout << msg.what() << std::endl;
}
}
};
int main()
{
divide test(6);
for (int i(0); i < 6; ++i)
{
test.get(i) = i * 3;
std::cout << test.get(i) << std::endl;
}
std::cout << "test.get(10): " << test.get(10) << std::endl;
test.get(3) = test.get(10);
std::cout << "test.get(3): " << test.get(3) << std::endl;
return 0;
}
If you catch exception in the divide::get method, it must somehow tell its caller that something went wrong. So implementation may look something like that:
class divide
{
//..
bool get(int nIndex, int* nResult);
//...
int main()
//...
int nRes = 0;
if(!test.get(10, &nRes))
cout << "Something is not right";
If there is many things that could go amiss, you could return some error code instead of bool. But if you use this method, there is no need in your exception class, you could simply return error without raising exception at all.
I have a small problem with inheritance in my code - it suddenly stops working when I add identical code in another "if" statement in my loop.
Here is the code I use for "main.cpp":
#include "bibl.h"
using namespace std;
int main()
{
int o;
Vec2 test;
while(1)
{
cout<<"1. Add item and show."<<endl<<"2. Show."<<endl;
cin>>o;
if(o==1)
{
InhItem a("Test",100);
test.addItem(&a);
cout<<"This show works:"<<endl;
test.getVec1(0)->getItem(0)->Show();//This code works.
}
else if(o==2)
{
cout<<"This show doesn't work:"<<endl;
test.getVec1(0)->getItem(0)->Show();//This doesn't.
}
}
system("pause");
return 0;
}
And the code for "bibl.h":
#ifndef TEST1
#define TEST1
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Item
{
protected:
string im;
string theme;
public:
Item(string im=" ", string theme=" "):im(im),theme(theme)
{
}
~Item()
{
}
string getTheme()
{
return theme;
}
virtual void Show()
{
}
};
class InhItem:public Item
{
int tst;
public:
InhItem(string im=" ", int tst=0):Item(im),tst(tst)
{
}
~InhItem()
{
}
void Show()
{
cout<<tst<<endl;
}
};
class Vec1
{
vector<Item*> Vec1a;
string theme;
public:
Vec1(string theme=" "):theme(theme)
{
}
~Vec1()
{
}
void addToVec1a(Item *item)
{
Vec1a.push_back(item);
}
string getTheme()
{
return theme;
}
Item *getItem(int p)
{
return Vec1a[p];
}
};
class Vec2
{
vector<Vec1*> Vec2a;
public:
Vec2()
{
}
~Vec2()
{
}
void addToVec2(Vec1 *vec1)
{
Vec2a.push_back(vec1);
}
void addItem(Item *item)
{
for(int i=0;i<=Vec2a.size();i++)
{
if(i==Vec2a.size())
{
addToVec2(new Vec1(item->getTheme()));
Vec2a[i]->addToVec1a(item);
break;
}
else if(Vec2a[i]->getTheme().compare(item->getTheme())==0)
{
Vec2a[i]->addToVec1a(item);
break;
}
}
}
Vec1 *getVec1(int r)
{
return Vec2a[r];
}
};
#endif
When I try to use the 2nd "if" after adding the item with 1st, it doesn't show - in 1st "if" test.getVec1(0)->getItem(0)->Show(); works, but in another it doesn't.
What is the cause of this problem and how can I fix it?