I have a problem. I must throw an exception in the constructor One() but do not know how do I suppose to catch it. Can someone suggest something? I have tried this method: Throwing exceptions from constructors , What happens if a constructor throws an exception?
My code:
class One
{
int a, b;
public:
One()
{
a = 7;
b = 0;
if (b == 0)
{
throw "except";
}
}
};
int main()
{
One j;
try
{
cout << "good";
}
catch(const char *str)
{
cout << str;
}
}
Place the variable definition inside the try block:
try
{
One j;
std::cout << "good";
}
catch(const char *str)
{
std::cout << str;
}
First of all, don't throw non exception. 2. If you call constructor inside the try block, you can catch it then.
#include <iostream>
#include <stdexcept>
class One
{
int a, b;
public:
One():
a(7),
b(0)
{
if (b == 0) {
throw std::runtime_error("except");
}
}
};
...
try {
One j;
std::cout << "good" << std::endl;
} catch(std::exception& e) {
std::cerr << e.what() << std::endl;
}
Another solution if you don't want to have the whole code inside a try..catch block:
int main()
{
One* j = nullptr;
try
{
j = new One;
cout << "good";
} catch (const char *str)
{
cout << str;
return 0;
}
// continue with object in j ...
}
And of course you should a smart pointer in this case:
int main()
{
std::unique_ptr< One> j;
try
{
j.reset( new One()); // or use std::make_unique<>()
cout << "good";
} catch (const char *str)
{
cout << str;
return 0;
}
// continue with object in j ...
}
Related
I am learning about exceptions from a book and try/catch and the OS should terminate the following program.
The book says, the message terminate called after throwing an instance of 'std::bad_alloc' should show up. But doesn't.
I am using Arch Linux and the program is not stopping. It runs, fills the RAM a bit linear until it doesn't (at about 90%), the processor is working a lot but no freezing and no terminating.
Is this a Windows only use case or how could I reproduce the error on a Linux/maybe Unix system?
#include <iostream>
#include <exception> //c++ exception
int main()
{
int *feld;
int loop = 1;
for(;;) //infinite loop
{
std::cout << "Loop number: " << loop << '\n';
try
{
feld = new int[10000];
loop++;
if (durchlauf == 100000) //since c++11
std::terminate();
}
catch(...)
{
std::cout << "Error, Program done.\n";
break;
}
}
return 0;
}
EDIT: I found out that my OOM killer is not working properly with swap enabled/at all. But c++ has its own termination process call
https://en.cppreference.com/w/cpp/error/terminate
It just doesn't issues an exception to print out the catch line.
Has anyone a hint to issue a catch termination?
I found the following code for you to program some terminations:
Hope that helps.
#include <iostream>
#include <stdexcept>
struct A {
int n;
A(int n = 0): n(n) { std::cout << "A(" << n << ") constructed successfully\n"; }
~A() { std::cout << "A(" << n << ") destroyed\n"; }
};
int foo()
{
throw std::runtime_error("error");
}
struct B {
A a1, a2, a3;
B() try : a1(1), a2(foo()), a3(3) {
std::cout << "B constructed successfully\n";
} catch(...) {
std::cout << "B::B() exiting with exception\n";
}
~B() { std::cout << "B destroyed\n"; }
};
struct C : A, B {
C() try {
std::cout << "C::C() completed successfully\n";
} catch(...) {
std::cout << "C::C() exiting with exception\n";
}
~C() { std::cout << "C destroyed\n"; }
};
int main () try
{
// creates the A base subobject
// creates the a1 member of B
// fails to create the a2 member of B
// unwinding destroys the a1 member of B
// unwinding destroys the A base subobject
C c;
} catch (const std::exception& e) {
std::cout << "main() failed to create C with: " << e.what();
}
Just for the sake of being helpful if someone steps into the same problem
a coded thrown exception after 100000 loops:
#include <iostream>
#include <exception> //c++ exception
int main()
{
int *feld;
int loop = 1;
for(;;) //infinite loop
{
std::cout << "Loop number: " << loop << '\n';
try
{
feld = new int[10000];
loop++;
if (loop == 1e5)
throw std::bad_alloc(); //has to be inside the try(){} scope
}
catch(...)
{
std::cout << "Error, Program done.\n";
break;
}
}
return 0;
}
I must be mistaken about something in the following code. I was experimenting, and couldn't understand why the make_shared cannot be called in the constructor, where as in initialize(), it works fine
class A {
public:
A() {
here = make_shared<A>();
}
void initialize(){
// here = make_shared<A>();
cout << &*here << endl;
cout << &here << endl;
}
void hereAddress() {
cout << &*here << endl;
}
private:
shared_ptr<A> here;
};
int main(){
vector<shared_ptr<A> > myA;
cout << "hi" << endl;
for (int i = 0; i < 10 ; ++i) {
myA.push_back(make_shared<A>() );
}
for (const auto& i : myA) {
i->initialize();
i->hereAddress();
}
return 0;
}
When I run this, I get exitcode -1. I appreicate your help.
This is because here = make_shared(); is invoking class constructor
and calling it inside constructor will make recursive calls to constructor causing segmentation faults
We need to call it outside constructor to avoid compiler complains.
try, throw and catch works, however, cout << devide(a,b) << endl occurs an error. How should I modify this code?
#include "stdafx.h"
#include <iostream>
using namespace std;
double devide(double a, double b) throw(int)
{
double result;
if (b == 0) throw 0;
result = a / b;
return result;
}
int main()
{
int a, b;
cin >> a >> b;
try {
devide(a, b);
}
catch (int c) {
cout << 100 << endl;
}
cout << devide(a,b) << endl;
return 0;
}
First of all throwing int is terrible idea, you should throw exception and there's header for it. You can write your own exceptions if you want but that doesn't matter right now.
Exceptions are for error handling don't use throws to "return different type" from functions and to do such barbaric things. You should throw only when there's no other way around.
In my example bellow I use std::logic_error because I think it suits the situation the best, since dividing by zero violates logical preconditions of any dividing function.
#include <iostream>
#include <stdexcept>
using namespace std;
double divide(double a, double b) {
if (b == 0) {
// you cannot divide by zero so you are throwing exception
// to handle this edge case which has no mathematical solution
throw logic_error("division by zero.");
}
return a / b;
}
int main() {
int a = 0,
b = 0;
cin >> a >> b;
try {
// result of divide must be evaluated before calling on operator<< of cout
// if it returns (b wasn't 0) it gets called and prints result into cout
// if it throws an exception (b was 0) it gets handled in catch block
cout << divide(a, b) << endl;
} catch (const logic_error& err) {
// printing error message
cout << err.what() << endl; // prints "division by zero."
}
return 0;
}
It is rather pointless to put the call inside a try when you later call it again outside of the try. You probably wanted something like this:
int main() {
int a, b, c;
cin >> a >> b;
try {
c = devide(a, b);
}
catch (exception e) {
c = 100;
}
cout << c << endl;
return 0;
}
#include <iostream>
using namespace std;
double devide(double a, double b)
{
double result;
if (b == 0) throw 0;
result = a / b;
return result;
}
int main()
{
int a, b;
int res=10;
while(res>0){
try {
cin >> a >> b;
devide(a, b);
res=-1;
}
catch (int c) {
cout << 100 << endl;
}
}
}
Put all on a loop and change the condition only in positive case.
I'm trying to join two pplx tasks using the && operator of task, where both sub tasks can throw exceptions.
I understand from the ppl documentation that I can catch an exception in a final, task-based continuation. This works in Casablanca as well.
However, I can catch only one exception in my final continuation. If both sub tasks throw, one remains unhandled.
Here's a minimal example illustrating my problem:
#include <pplx/pplxtasks.h>
#include <iostream>
int main(int argc, char *argv[])
{
int a = 0; int b = 0;
auto t1 = pplx::create_task([a] { return a+1; })
.then([](int a) { throw std::runtime_error("a");
return a+1; });
auto t2 = pplx::create_task([b] { return b+1; })
.then([](int b) { throw std::runtime_error("b");
return b+1; });
(t1 && t2)
.then([] (std::vector<int>) { /*...*/ })
.then([] (pplx::task<void> prev) {
try {
prev.get();
} catch (std::runtime_error e) {
std::cout << "caught " << e.what() << std::endl;
}
});
std::cin.get();
}
The try/catch is able to catch whichever of the two exceptions occurs first. How can I catch the other?
You would have to add a final task-based continuation to each sub-task.
I would suggest re-throwing any exception you catch, however, that would likely be a bad idea since the continuation task doesn't realize that the 2 exceptions are equivalent see below example for proof.
Output:
caught a
caught final a
caught b
Also, if you remove the sleep, you will receive a "Trace/breakpoint trap" exception.
#include <pplx/pplxtasks.h>
#include <iostream>
int main(int argc, char *argv[])
{
int a = 0; int b = 2;
auto t1 = pplx::create_task([a] { return a+1; })
.then([](int a) { throw std::runtime_error("a"); return a+1; })
.then([] (pplx::task<int> prev)
{
int retVal = -1;
try
{
retVal = prev.get();
}
catch (std::runtime_error e)
{
std::cout << "caught " << e.what() << std::endl;
throw e;
}
return retVal;
});
auto t2 = pplx::create_task([b] { return b+1; })
.then([](int b) { throw std::runtime_error("b"); return b+1; })
.then([] (pplx::task<int> prev)
{
int retVal = -1;
try
{
sleep(1);
retVal = prev.get();
}
catch (std::runtime_error e)
{
std::cout << "caught " << e.what() << std::endl;
throw e;
}
return retVal;
});
(t1 && t2)
.then([] (std::vector<int> v) { for(int i : v) { std::cout << i << std::endl; } })
.then([] (pplx::task<void> prev)
{
try
{
prev.get();
}
catch (std::runtime_error e)
{
std::cout << "caught final " << e.what() << std::endl;
}
}).get();
}
class A {
public:
void f()
{
cout << "A()" << endl;
}
};
class B {
public:
void f()
{
cout << "B()" << endl;
}
};
class C {
public:
void f()
{
cout << "C()" << endl;
}
};
void print(boost::any& a)
{
if(A* pA = boost::any_cast<A>(&a))
{
pA->f();
}
else if(B* pB = boost::any_cast<B>(&a))
{
pB->f();
}
else if(C* pC = boost::any_cast<C>(&a))
{
pC->f();
}
else if(string s = boost::any_cast<string>(a))
{
cout << s << endl;
}
else if(int i = boost::any_cast<int>(a))
{
cout << i << endl;
}
}
int main()
{
vector<boost::any> v;
v.push_back(A());
v.push_back(B());
v.push_back(C());
v.push_back(string("Hello boy"));
v.push_back(24);
for_each(v.begin(), v.end(), print);
}
I'm getting this error in print() when testing for string using Visual Studio 2010:
error C2451: conditional expression of type 'std::string' is illegal
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
else if(string s = boost::any_cast<string>(a))
This line is causing you problems. string s is not a pointer, it's a stack variable. You can't do a check for null.
The reason you can do a check on the integer below is that integers implicitly map to bool.
0 -> FALSE
1 -> TRUE
You shouldn't use any_cast on a reference here, because it throws a bad_any_cast exception if the type isn't right. Use a pointer in the last two cases like you did with the first three:
else if(string* s = boost::any_cast<string*>(&a))
{
cout << *s << endl;
}
else if(int* i = boost::any_cast<int*>(&a))
{
cout << *i << endl;
}