#include<iostream>
using namespace std;
class test
{
public:
test()
{
cout<<"hello";}
~test()
{
cout<<"hi";
throw "const";
}
void display()
{
cout<<"faq";
}
};
int main()
{
test t;
try{
}
catch(char const *e)
{
cout<<e;
}
t.display();
}
output:
i know by throwing exception from destructor i'm violating basic c++ laws but still i want to know is their any way the exception can be handled.
Your destructor runs outside the try-catch block - t's scope is the main function. but then raising exceptions from a destructor is a Bad IdeaTM.
There's nothing in your try block. Try this:
try
{
test t;
}
catch(char const *e)
{
cout << e;
}
Also, in general throwing an exception in a destructor is a bad idea (as with most rules, there are exceptions).
The creation of your test object must be done inside the try block:
try
{
test t;
t.Display();
}
and a full version:
#include<iostream>
using namespace std;
class test
{
public:
test()
{
cout << "hello" << endl;
}
~test()
{
cout << "hi" << endl;
throw "const";
}
void display()
{
cout << "faq" << endl;
}
};
int main()
{
try
{
test t;
t.display();
}
catch(char const *e)
{
cout << e << endl;
}
}
Why not just call the destructor function explicitly in try block?
Related
I am working on a class assignment to create three classes nested inside each other. I need to make constructors and deconstructors for each that have a message that goes along with them. Finally, I need to create an instance of each class using new and call the display() function to show their message, followed by delete.
I have completed the assignment but in the wrong way, and I am confused about how I can properly put the code into the heap instead of the stack (as I was advised by my course tutor).
This is what I started with: (this code seems to work well, but does not fulfill the assigned project)
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
class Hen {
public:
Hen();
~Hen();
string display(void) {
return ("Im a Hen");
}
class Nest;
friend Nest;
class Nest {
public:
Nest();
~Nest();
string display(void) {
return ("Im a Nest");
}
class Egg;
friend Egg;
class Egg {
public:
Egg();
~Egg();
string display(void) {
return ("Im an egg");
}
};
};
};
Hen::Hen() {
cout << "I construct Hens" << endl;
}
Hen::~Hen() {
cout << "I deconstruct Hens" << endl;
}
Hen::Nest::Nest() {
cout << "I construct Nests" << endl;
}
Hen::Nest::~Nest() {
cout << "I deconstruct Nests" << endl;
}
Hen::Nest::Egg::Egg() {
cout << "I construct Eggs" << endl;
}
Hen::Nest::Egg::~Egg() {
cout << "I deconstruct Eggs" << endl;
}
int main() {
Hen hone;
Hen::Nest none;
Hen::Nest::Egg eone;
string h, n, e;
h = hone.display();
n = none.display();
e = eone.display();
cout << h << "\n" << n << "\n" << e << endl;
}
Where I am stuck is when I try to implement my code inside the heap, it seems to break by the second class:
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
class Hen {
public:
void display() {
cout << "Im a Hen" << endl;
}
class Nest;
friend Nest;
class Nest {
public:
void display() {
cout << "Im a Nest" << endl;
}
class Egg;
friend Egg;
class Egg {
public:
void display() {
cout << "Im an egg" << endl;
}
};
};
};
int main() {
Hen *hone = new Hen();
Hen::Nest *none = new Nest();
hone -> display();
none -> display();
}
Question 1:
If I remove all the information related to nest, the program runs Hen just fine and returns the "I'm a hen" statement. But, when I add in nest, the warning I recieve is
"error: expeected type-specifier before 'Nest'
Hen::Nest *none = new Nest();"
I do not understand what I am doing wrong as I did the exact same process for Hen and it worked. I do know that the error must be in the way Nest gets called through hen?
I apologize if this question is obvious, but I am just starting c++ and do not understand why I am getting these messages...
Thanks for your help!
I want to defer the construction of my member variable until the constructor's body and I am trying to use union to do that. Until now, it's achieving what I want but I want to ask is there any reason I shouldn't do this?
Example:
#include <iostream>
struct A {
A() {
std::cout << "Construct A" << std::endl;
}
~A() {
std::cout << "Destruct A" << std::endl;
}
};
struct B {
A a;
};
template <typename T>
union U {
char a{};
T buffer;
U() {}
~U() {
buffer.~T();
}
};
struct C {
U<B> u;
C() {
try {
new (&u.buffer) B();
} catch (...) {
}
}
};
Edit: Add sample usage
One of the reason you should not use the work around is that it does not make sense.
Apply try-catch on hole constructor will work well.
struct C {
A a;
C() try {
} catch (...) {
}
};
std::optional seems to be a great way to do this if you're at C++17.
#include <iostream>
#include <optional>
#include <stdexcept>
struct A {
A(bool fail = false) {
std::cout << "Attempting to construct A" << std::endl;
if (fail) {
throw std::runtime_error("Failed to construct A");
}
else {
std::cout << "Succeeded in constructing A" << std::endl;
}
}
~A() {
std::cout << "Destruct A" << std::endl;
}
};
struct B {
std::optional<A> a;
B(bool fail = false) {
try {
a.emplace(fail);
}
catch (std::runtime_error& ex) {
// fall back to a safe construction
std::cout << "Falling back to safe A construction" << std::endl;
a.emplace();
}
}
};
int main() {
{
B b_good; // should be fine
}
{
B B_bad(true); // should catch the exception and fall back
}
}
output:
Attempting to construct A
Succeeded in constructing A
Destruct A
Attempting to construct A
Failed to construct A
An option that forgoes the size of std::optional is to have the unallocated buffer, but (for type safety) access it through a reference.
#include <iostream>
#include <optional>
#include <stdexcept>
struct A {
A(bool fail = false) {
std::cout << "Attempting to construct A" << std::endl;
if (fail) {
throw std::runtime_error("Failed to construct A");
}
else {
std::cout << "Succeeded in constructing A" << std::endl;
}
}
~A() {
std::cout << "Destruct A" << std::endl;
}
};
struct B {
char a_buff_[sizeof(A)];
A& a_;
B(bool fail = false) : a_(*reinterpret_cast<A*>(a_buff_)) {
try {
new (&a_) A(fail);
}
catch (std::runtime_error& ex) {
std::cout << ex.what() << std::endl;
std::cout << "Falling back to safe A construction" << std::endl;
new (&a_) A();
}
}
~B() { a_.~A(); }
B(const B& other) : a_(other.a_) {}
B& operator=(const B& other) {
a_ = other.a_;
}
};
int main() {
{
B b_good; // should be fine
}
{
B b_bad(true); // should catch the exception and fall back
}
}
Attempting to construct A
Succeeded in constructing A
Destruct A
Attempting to construct A
Failed to construct A
Falling back to safe A construction
Attempting to construct A
Succeeded in constructing A
Destruct A
I was studying c++ language with shared pointer and builder pattern.
I have written following code that is not working but I don't understand why it emits run-time error.
Could you tell me why it is not working well and how can I solve this problem to work well?
#include <iostream>
#include <memory>
#include <string>
using namespace std;
class Popup
{
public:
Popup(int value, string str){
this->v = value;
this->str = str;
}
virtual void print() = 0;
int v;
string str;
};
typedef shared_ptr<Popup> PopupPtr;
class PopupA : public Popup
{
public:
PopupA(int v, string str) : Popup(v, str) { }
virtual void print() {
cout << "PopupA" << endl;
}
};
typedef shared_ptr<PopupA> PopupAPtr;
class PopupB : public Popup
{
public:
PopupB(int v, string str) : Popup(v, str) { }
virtual void print() {
cout << "PopupB" << endl;
}
};
typedef shared_ptr<PopupB> PopupBPtr;
class Builder
{
public:
PopupPtr popupPtr;
Builder() { };
shared_ptr<Builder> init(int value, string str) {
shared_ptr<Builder> builder;
switch (value)
{
case 1:
popupPtr = PopupAPtr(new PopupA(value, str));
break;
case 2:
popupPtr = PopupBPtr(new PopupB(value, str));
break;
default:
cout << "default error" << endl;
break;
}
if (popupPtr) {
builder = shared_ptr<Builder>(this);
}
else {
cout << "popup is null" << endl;
}
if (!builder) {
cout << "builder is null" << endl;
}
return builder;
}
PopupPtr build()
{
if (!popupPtr) {
cout << "popup is null" << endl;
}
return PopupPtr(popupPtr);
}
};
typedef shared_ptr<Builder> BuilderPtr;
int main()
{
BuilderPtr builderPtr = BuilderPtr(new Builder());
PopupPtr popupPtr1 = builderPtr->init(1, "111111111111")->build();
popupPtr1->print();
PopupPtr popupPtr2 = builderPtr->init(2, "222222222222")->build();
popupPtr2->print();
return 0;
}
Thanks in advance for your answers and sorry for my poor english. If you don't understand my question please make a comment.
Your problem is this line:
builder = shared_ptr<Builder>(this);
This will not create a copy of the std::shared_ptr already tracking this, nor will it affect the reference count of it. This creates an entirely new shared pointer which will track this independently, causing a double-delete when both of the reference counts hit zero.
Fortunately, the standard library provides a solution to this problem in the form of std::shared_from_this.
First you need to enable this for your class:
class Builder : std::enable_shared_from_this<Builder>
{
//...
};
Then instead of creating a new std::shared_ptr from this, call std::shared_from_this:
builder = std::shared_from_this();
I have a simple piece of code (Checker) which carries out some consistency checks on the elements of a vector (pps)
try{
const Checker& results = std::for_each(pps.begin(), pps.end(), Checker());
!results.diagnostic();
}
catch(std::bad_alloc&){
cout << "the check operation failed: out of memory" << endl;
}
Checker has a member function (diagnostic) which outputs the results of this check.
The problem is: if for some reason (std::bad_alloc, for example) the check operation gets interrupted, i would like to have the already produced diagnostic available. Is it possible without recurring to a "substantial rewrite" allowing me to do something like:
Checker::Diagnostic diagnostic;
try{
std::for_each(pps.begin(), pps.end(), Checker(diagnostic));
}
catch(std::bad_alloc&){
cout << "the check operation failed: out of memory" << endl;
}
diagnostic.output();
This would look unnatural, since the return of std::for_each is intended for the exact purpose of being able to do such things, and the exceptional flow of control would dominate the look of the code.
I would prefer to use the class like this:
Checker checker;
checker.doCheck(pps);
checker.diagnostic();
Or:
const Checker checker(pps);
checker.diagnostic();
That way, you can hide the details of the check in doCheck() (first example) or in the constructor (second example).
For example:
#include <algorithm>
#include <iostream>
#include <vector>
#include <boost/bind.hpp>
using ImportantItems = std::vector<int>;
class Checker {
public:
Checker(const int criticalItem) : criticalItem(criticalItem) { }
void doCheck(const ImportantItems& items)
{
accumulatedSum = 0;
try {
std::for_each(
items.begin(), items.end(),
boost::bind(&Checker::performExtensiveCheckingOnAnItem, this, _1));
this->dataOk = true;
}
catch (const std::runtime_error& e) {
this->dataOk = false;
}
std::cout << "AddAccumulated sum: " << accumulatedSum << std::endl;
}
void diagnostic() const
{
if (this->dataOk) {
std::cout << "Everything was fine in last check" << std::endl;
}
else {
std::cout << "Serious problems encountered" << std::endl;
}
}
private:
void performExtensiveCheckingOnAnItem(const int anItem)
{
if (criticalItem == anItem) {
throw std::runtime_error("Critical situation");
}
accumulatedSum += anItem;
}
const int criticalItem;
int accumulatedSum{};
bool dataOk{false};
};
int main()
{
const int criticalItem(5);
const ImportantItems importantItems{1, 2, 3, 4/*, criticalItem*/};
Checker checker(criticalItem);
checker.doCheck(importantItems);
checker.diagnostic();
return 0;
}
I have some troubles with an application that I made. std::move destroys your object when you move it to vector pushback. Here a small example:
#include <string>
#include <iostream>
#include <vector>
using namespace std;
class FileSetting
{
private:
FileSetting(FileSetting &fileSetting) { cout << "Copy\n"; }
public:
FileSetting(std::string name, void * value, int size) { cout << "Create\n"; }
FileSetting(FileSetting &&fileSetting) { cout << "Move\n"; }
~FileSetting() { cout << "Destroy\n"; }
void test() { cout << "Test\n"; }
};
int main()
{
vector<FileSetting> settings;
{
char * test = "test";
FileSetting setting("test", test, strlen(test) * sizeof(char));
settings.push_back(std::move(setting));
}
settings[0].test();
cout << "Done!\n";
return 0;
}
The output will be:
Create
Move
Destroy
Test
Done!
Destroy
How can I make sure that destroy only will be called when FileSetting goes out of scope and not when I move it. I'm trying to avoid pointer.
std::move() doesn't destroy the object. The "Destroy" you're getting is from setting going out of scope.