.dp-highlighter { font-family: "Consolas", "Monaco", "Courier New", Courier, monospace; font-size: 12px; background-color: #E7E5DC; width: 99%; overflow: auto; margin: 18px 0 18px 0 !important; padding-top: 1px; /* adds a little border on top when controls are hidden */ } /* clear styles */ .dp-highlighter ol, .dp-highlighter ol li, .dp-highlighter ol li span { margin: 0; padding: 0; border: none; } .dp-highlighter a, .dp-highlighter a:hover { background: none; border: none; padding: 0; margin: 0; } .dp-highlighter .bar { padding-left: 45px; } .dp-highlighter.collapsed .bar, .dp-highlighter.nogutter .bar { padding-left: 0px; } .dp-highlighter ol { list-style: decimal; /* for ie */ background-color: #fff; margin: 0px 0px 1px 45px !important; /* 1px bottom margin seems to fix occasional Firefox scrolling */ padding: 0px; color: #5C5C5C; } .dp-highlighter.nogutter ol, .dp-highlighter.nogutter ol li { list-style: none !important; margin-left: 0px !important; } .dp-highlighter ol li, .dp-highlighter .columns div { list-style: decimal-leading-zero; /* better look for others, override cascade from OL */ list-style-position: outside !important; border-left: 3px solid #6CE26C; background-color: #F8F8F8; color: #5C5C5C; padding: 0 3px 0 10px !important; margin: 0 !important; line-height: 14px; } .dp-highlighter.nogutter ol li, .dp-highlighter.nogutter .columns div { border: 0; } .dp-highlighter .columns { background-color: #F8F8F8; color: gray; overflow: hidden; width: 100%; } .dp-highlighter .columns div { padding-bottom: 5px; } .dp-highlighter ol li.alt { background-color: #FFF; color: inherit; } .dp-highlighter ol li span { color: black; background-color: inherit; } /* Adjust some properties when collapsed */ .dp-highlighter.collapsed ol { margin: 0px; } .dp-highlighter.collapsed ol li { display: none; } /* Additional modifications when in print-view */ .dp-highlighter.printing { border: none; } .dp-highlighter.printing .tools { display: none !important; } .dp-highlighter.printing li { display: list-item !important; } /* Styles for the tools */ .dp-highlighter .tools { padding: 3px 8px 3px 10px; font: 9px Verdana, Geneva, Arial, Helvetica, sans-serif; color: silver; background-color: #f8f8f8; padding-bottom: 10px; border-left: 3px solid #6CE26C; } .dp-highlighter.nogutter .tools { border-left: 0; } .dp-highlighter.collapsed .tools { border-bottom: 0; } .dp-highlighter .tools a { font-size: 9px; color: #a0a0a0; background-color: inherit; text-decoration: none; margin-right: 10px; } .dp-highlighter .tools a:hover { color: red; background-color: inherit; text-decoration: underline; } /* About dialog styles */ .dp-about { background-color: #fff; color: #333; margin: 0px; padding: 0px; } .dp-about table { width: 100%; height: 100%; font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; } .dp-about td { padding: 10px; vertical-align: top; } .dp-about .copy { border-bottom: 1px solid #ACA899; height: 95%; } .dp-about .title { color: red; background-color: inherit; font-weight: bold; } .dp-about .para { margin: 0 0 4px 0; } .dp-about .footer { background-color: #ECEADB; color: #333; border-top: 1px solid #fff; text-align: right; } .dp-about .close { font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; background-color: #ECEADB; color: #333; width: 60px; height: 22px; } /* Language specific styles */ .dp-highlighter .comment, .dp-highlighter .comments { color: #008200; background-color: inherit; } .dp-highlighter .string { color: blue; background-color: inherit; } .dp-highlighter .keyword { color: #069; font-weight: bold; background-color: inherit; } .dp-highlighter .preprocessor { color: gray; background-color: inherit; }

Wednesday, March 4, 2009

why use shared_from_this() ?

Why would you need to use shared_from_this on an object? As the name implies, if you want to pass a shared pointer to *this (pointer to current object), then you use shared_from_this.

What happens if you don't? Well, a scenario could happen where you wrap *this pointer in a smart pointer from a member function, expecting that to work just fine. But what happens when you do that is you create another shared_ptr to *this with reference count of 1. When this member function exits, the shared_ptr gets destroyed, and your *this pointer is deleted, causing the destructor of the object to be called.

An example will make this clearer:
#include <iostream>
#include <boost/shared_ptr.hpp>

class Bar;
void foo(const boost::shared_ptr<Bar>& ptr);

class Bar
{
public:
void process()
{
foo(boost::shared_ptr<Bar>(this));
}
void print() const {std::cout << "I am still alive!!" << std::endl; }

~Bar() { std::cout << "Uh oh... I am dead!!" << std::endl; }
};

void foo(const boost::shared_ptr<Bar>& ptr)
{
ptr->print();
}

int main()
{
boost::shared_ptr<Bar> sPtr(new Bar());
sPtr->process();
sPtr->print();
std::cout << "Just before leavnig main " << std::endl;
sPtr->print();
return 0;
}


When you run this code (fix any errors first), it'll crash. The reason being, when the function process exits, the temporary shared_ptr resets its refcount to 0, and the *this object gets deleted. Then when main tries to delete the object again upon exit, it crashes.

To fix this, we use shared_from_this(), which will simply make sure that we get a smart pointer *this instead of a raw pointer *this. Read more about it in the boost docs


#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

class Bar;
void foo(const boost::shared_ptr<Bar>& ptr);

class Bar : public boost::enable_shared_from_this<Bar>
{
public:
void process()
{
foo(shared_from_this());
}
void print() const {std::cout << "I am still alive!!" << std::endl; }

~Bar() { std::cout << "Uh oh... I am dead!!" << std::endl; }
};

void foo(const boost::shared_ptr<Bar>& ptr)
{
ptr->print();
}

int main()
{
boost::shared_ptr<Bar> sPtr(new Bar());
sPtr->process();
sPtr->print();
std::cout << "Just before leavnig main " << std::endl;
sPtr->print();
return 0;
}

3 comments :

عبدالعزيز said...

Not much C++ programming I do; but I liked the pointer tidbit. I came to get code formatting link. Yellah Sher'ob, Salam.

YemeniProgrammer said...

Use this tool for formatting code:

http://formatmysourcecode.blogspot.com/

The other one I used truncated my code :(

dk said...
This comment has been removed by the author.