1 #include <iostream> 2 #include <vector> 3 4 class Bad { 5 public: 6 7 Bad(int v) { 8 data = new std::vector<int>(); 9 data->push_back(v); 10 } 11 12 // No copy constructor. Using default. 13 14 // No assignment operator. Using default. 15 16 std::vector<int> *data; 17 18 void add(int v) { 19 data->push_back(v); 20 } 21 22 void show() { 23 std::vector<int>::iterator it; 24 for (it = data->begin(); it != data->end(); ++it) { 25 std::cout << *it << " "; 26 } 27 std::cout << std::endl; 28 } 29 }; 30 31 class Good { 32 public: 33 34 Good(int v) { 35 data = new std::vector<int>(); 36 data->push_back(v); 37 } 38 39 // Copy constructor. 40 Good(const Good& rhs) { 41 42 std::cout << "Copy constructor called" << std::endl; 43 44 if (this == &rhs) { 45 // Copy to self. No action required. 46 return; 47 } 48 49 this->data = new std::vector<int>(); 50 51 // Copy elements in data manually! 52 std::vector<int>::iterator it; 53 for (it = rhs.data->begin(); it != rhs.data->end(); ++it) { 54 this->data->push_back(*it); 55 } 56 } 57 58 // Assignment operator. 59 Good& operator=(const Good& rhs) { 60 std::cout << "Assignment operator called" << std::endl; 61 62 if (&rhs == this) { 63 return *this; 64 } 65 66 // Copy elements in data manually! 67 this->data->clear(); 68 std::vector<int>::iterator it; 69 for (it = rhs.data->begin(); it != rhs.data->end(); ++it) { 70 this->data->push_back(*it); 71 } 72 73 return *this; 74 } 75 76 std::vector<int> *data; 77 78 void add(int v) { 79 data->push_back(v); 80 } 81 82 void show() { 83 std::vector<int>::iterator it; 84 for (it = data->begin(); it != data->end(); ++it) { 85 std::cout << *it << " "; 86 } 87 std::cout << std::endl; 88 } 89 }; 90 91 int main() { 92 93 std::cout << "<<<< Testing Bad. >>>>" << std::endl; 94 95 Bad b1 = Bad(10); 96 Bad b2 = b1; // Calls copy constructor. 97 98 b2.show(); // Prints 10 . 99 b1.add(20); 100 b2.show(); // Prints 10 20 (!) 101 102 std::cout << "<<<< Testing Good. >>>>" << std::endl; 103 104 Good g1 = Good(10); 105 Good g2 = g1; // Calls copy constructor. 106 107 g2.show(); // Prints 10 . 108 g1.add(20); 109 g2.show(); // Prints 10 . :) 110 111 g2 = g1; // Calls assignment operator. 112 g2.show(); // Prints 10 20 . :) 113 }
Tuesday, June 13, 2017
Copy constructor or assignment operator
Using default copy constructor or assignment operator may cause misleading behavior as following code I wrote.
Thursday, March 5, 2015
MathJax for writing an equation on web page.
<pre>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<p>$$ Equation here $$</p>
Then will look like,
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<p>$$ Equation here $$</p>
Then will look like,
$$ \textit{h}_{\theta }\left ( \textit{x} \right ) = \theta _{0} + \theta _{1} \textit{x} _{1} + \cdots + \theta _{n} \textit{x} _{n} $$
Wednesday, July 30, 2014
Justify alignment
I didn't know that it's called 'Justify alignment'. I decided to implement with C#. Process is simple. Get text and line width, split text into words, make them group of words for each line, print line after padding it with seperator so that start and end of a line will be characters as possible as it can.
Then the output is,
namespace Justify { class Program { /// <summary> /// Does justify alignment for given text. /// </summary> /// <param name="text">string input</param> /// <param name="lineWidth">Line width</param> /// <returns>List of lines aligned with justify option.</returns> static List<string> Justify(string text, int lineWidth) { var output = new List<string>(); // 1. Split text into list of words. List<List<string>> wordLists = getWords(text, lineWidth); // 2. Do justify align per each line. foreach (var list in wordLists) { output.Add(padding(list, lineWidth)); } return output; } static private List<List<string>> getWords(string text, int lineWidth) { var output = new List<List<string>>(); // Split whole text into words. string[] words = text.Split(new char[] { ' ' }); // current width of words with seperator(' ') included. int length = 0; // List of words to be in a line. var wordList = new List<string>(); for (int i = 0; i < words.Length; ++i) { // If length of current word is the same or longer than line width, if (length == 0 && words[i].Length >= lineWidth) { // Cut it with line length and put it into word list. wordList.Add(words[i].Substring(0, lineWidth)); // If a word is longer than line width, if (words[i].Length > lineWidth) { // Take the rest of the word and put it into word list back // so the rest part would be in next line. words[i] = words[i].Substring(lineWidth, words[i].Length - lineWidth); i--; } // Put a line into output list. output.Add(wordList); wordList = new List<string>(); } // If current line can't contain current word, // 1 for seperator ' ' else if (length + 1 + words[i].Length > lineWidth) { // pub a line into output list. output.Add(wordList); // Prepare a new line and reset counter. wordList = new List<string>(); length = 0; i--; } // Else, put a word and increase counter. else { wordList.Add(words[i]); length += words[i].Length + 1; } } return output; } // This does justify. For example, if words ["How", "are", "you"] // and line width 15 is given, output will be // 123456789012345 <- index // How are you static private string padding(List<string> wordList, int lineWidth) { // Return empty string if empty list is given. if (wordList.Count == 0) return string.Empty; int i = 0; int length = 0; // Length is sum of all words length in the list. foreach (var word in wordList) { length += word.Length; } // Here we append seperator to all words in the list // until length is as same as lineWidth. while (length < lineWidth) { if (i == 0 || i != wordList.Count - 1) { wordList[i] = wordList[i] + " "; length++; } i = (i + 1) % wordList.Count; } return string.Join<string>("", wordList); } static void Main(string[] args) { string text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; var output = Justify(text, 30); foreach (var line in output) Console.WriteLine(line); } } }
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim
Wednesday, June 18, 2014
Producer and multi-consumer sample code using C# (2)
If we use concurrent queue, we can just throw away all the complicated lock mechanism or concurrency and focus on the logic itself. Not sure if c# concurrent queue implemented it with lock free mechanism but producer-consumer code can be written in less than 100 lines.
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SimpleProducerConsumer { class Producer { private ConcurrentQueue<int> q; public Producer(ConcurrentQueue<int> q) { this.q = q; } public void Run() { while (true) { int w; Console.Write("Gimme a work: "); w = Convert.ToInt32(Console.ReadLine()); this.q.Enqueue(w); Console.WriteLine(); } } } class Consumer { private ConcurrentQueue<int> q; public Consumer(ConcurrentQueue<int> q) { this.q = q; } public void Run() { while (true) { int w = -1; if (q.TryDequeue(out w)) { Console.WriteLine("\nExtracted {0} from the queue and processed", w); } Thread.Sleep(1000); } } } class Program { static void Main(string[] args) { var q = new ConcurrentQueue<int>(); var producer = new Producer(q); var consumer = new Consumer(q); Thread tProducer = new Thread(producer.Run); Thread tConsumer = new Thread(consumer.Run); tConsumer.Start(); tProducer.Start(); } } }
Saturday, January 18, 2014
C# Interlocked
Like CLI, STI inline assembly in C or like scope lock in C++, there is interlocked class for atomic operation in C#. Easy and good to make code look clean.
Tuesday, July 16, 2013
Producer and multi-consumer sample code using C#
As a practice of multi-thread code using C#, I wrote a sample code of producer and consumer model. I used custom threadpool so that workers never end until they receive end signal and check work queue timely.
Producer and consumer model is simple. There is a task queue. Producer puts tasks into the queue. And consumer process a task when it finds in the queue. The code has one producer and multiple consumers.
I used basic lock mechanism. Because there's no Monitor()/Pulse() here, producer and consumer should check the queue timely with Sleep() instead.
Producer and consumer model is simple. There is a task queue. Producer puts tasks into the queue. And consumer process a task when it finds in the queue. The code has one producer and multiple consumers.
I used basic lock mechanism. Because there's no Monitor()/Pulse() here, producer and consumer should check the queue timely with Sleep() instead.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // For producer and consumer threads. using System.Threading; namespace ProConSample { /** * In this sample, 2,000 tasks will be generated by a producer * and 10 consumers(workers) will process them. */ class Conf { public const int numTasks = 2000; public const int numWorkers = 10; public const int maxTaskValue = 100; public const bool debugMode = true; } class Util { public static void DEBUG(string format, params object[] args) { if (Conf.debugMode) { Console.WriteLine(format, args); } } } /** * WorkQueue has a lock so that only one thread at a time can * access to it. */ class WorkQueue { public readonly object aLock = new object(); private Queue<int> _queue; public WorkQueue() { _queue = new Queue<int>(); } public void Enqueue(int v) { // TODO: exception handling for _queue.Length reaches Max value. _queue.Enqueue(v); } public int Dequeue() { // TODO: exception handling for _queue is empty return _queue.Dequeue(); } public int Length { get { return _queue.Count; } } } /** * Producer puts tasks into workQueue. */ class Producer { private Random _random = new Random(); private WorkQueue _queue; private const int _sleepInterval = 1; public Producer(WorkQueue q) { _queue = q; } public void Start() { Util.DEBUG("Producer started"); for (int i = 0; i < Conf.numTasks; ++i) { int v = _random.Next(Conf.maxTaskValue); lock(_queue.aLock) { _queue.Enqueue(v); } Util.DEBUG("[Producer] Enqueued {0}", v); /** * If you don't sleep at all, this function will occupy * a core till it ends. If this happens in a single core * machine, consumers can not start its routine until * the producer ends its work. */ Thread.Sleep(_sleepInterval); } Util.DEBUG("Producer ended"); } } /** * Consumers check workQueue. If there's a task, consumer will * dequeue a task and will process with it. */ class Consumer { private WorkQueue _queue; private int _taskLeft; public int NumTaskDone { get; set; } public bool EvEnd { get; set; } private const int _sleepInterval = 1; public Consumer(WorkQueue q) { _queue = q; _taskLeft = 0; EvEnd = false; NumTaskDone = 0; } public void Start() { Util.DEBUG("Consumer started"); while (true) { int v = 0; // Check if we have a task to do lock (_queue.aLock) { _taskLeft = _queue.Length; if (_taskLeft > 0) { v = _queue.Dequeue(); } } // Process a task. if (_taskLeft > 0) { Util.DEBUG("[Worker] Dequeued {0}", v); NumTaskDone++; } /** * Ending condition: * No work left in the queue and ending event received. */ if (EvEnd && _taskLeft == 0) { break; } /** * If consumer doesn't sleep here, it will hold a core. * If consumers hold all cores so that the producer has * no chance to get core to enqueue, deadlock occurs. */ Thread.Sleep(_sleepInterval); } Util.DEBUG("Consumer ended: processed {0} tasks", NumTaskDone); } } /** * ThreadPool which contains consumers and threads in the list. */ class ThreadPool { Consumer[] consumers = new Consumer[Conf.numWorkers]; Thread[] threads = new Thread[Conf.numWorkers]; public ThreadPool(WorkQueue q) { for (int i = 0; i < Conf.numWorkers; ++i) { consumers[i] = new Consumer(q); threads[i] = new Thread(new ThreadStart( consumers[i].Start )); } } public void Start() { for (int i = 0; i < Conf.numWorkers; ++i) { threads[i].Start(); } } public void SetEndEvent() { for (int i = 0; i < Conf.numWorkers; ++i) { consumers[i].EvEnd = true; } } public void Join() { for (int i = 0; i < Conf.numWorkers; ++i) { threads[i].Join(); } } } class ProCon { static void Main(string[] args) { // Create a work queue. WorkQueue workQueue = new WorkQueue(); // Create a producer. Producer producer = new Producer(workQueue); Thread tProducer = new Thread(new ThreadStart(producer.Start)); // Create consumers. ThreadPool tConsumers = new ThreadPool(workQueue); // Start producer and consumers tProducer.Start(); tConsumers.Start(); // If producing ends, set an end event signal. tProducer.Join(); tConsumers.SetEndEvent(); /** * TODO: Is there any method to wait all thread in a specific * list ended? */ // Join consumers thread ended tConsumers.Join(); } } }
Wednesday, June 12, 2013
Using libssh2 on multithread code.
Day1.
I have a daemon running on CentOS4.3. By the way, an operator told me that the server it resides should be moved to the other rack. So I decided to move and upgrade OS version to CentOS6.3 with gcc-4.4.6 during migration. I moved and compiled. But it stopped after several minutes. The daemon spawns many threads and each thread has socket connected via boost::asio. Each thread passes connected socket to libssh2_session_handshake() for ssh connection. Libssh2 library is used here. It uses libgcrypt library to generate 16 bytes of random numbers. However, gdb didn't show call stack when it goes into library routine(showed function name like ???() ). To know where it stops, I downloaded each libraries(libssh2, libgcrypt, libgpg-error) and compiled them again. Gdb finally showed that libgcrypt tries to attain mutex lock to access random pool for generating random number, it stops because it designed to fail to get mutex lock and assert. It works well on single thread environment. This isn't typical way to use libssh2 library. No helpful answer found at Google... TT.
Day2.
After doing more googling, bingging I found interesting information. Acturally both libssh2 and libgcrypt are designed for multithread environment. There was nothing to do for libssh2 to run it on MT-ed code. But something should have been done for libgcrypto. Because it doesn't know which thread mechanism is used in the host, it implemented two types of structures and functions for mutex as a macro. One for pthread and the other for pth. So the application code that I'm managing should select which macro to be used by adding following lines before it forks thread(pthread selected).
#include <gcrypt.h>
GCRY_THREAD_OPTION_PTHREAD_IMPL;
And it also should call gcry_control() so that the library assign callbacks to each functions related to mutex it uses like below.
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
Several day has passed, and the server works well up to now. Hooray! :)
Thursday, March 28, 2013
How to check if a value is NaN in C++
I didn't know until now that if (a != a) returns true only when a is NaN.
#include <iostream>
#include <cmath>
using namespace std;
int main() {
float a = sqrt(-1); // nan
if (a != a) {
cout << "It's NaN!" << endl;
cout << a << endl; // prints 'nan'
}
else {
cout << "It's OK!" << endl;
}
return 0;
}
Friday, November 23, 2012
Python threads with queue.
import threading import Queue import urllib2 import time urls = ["http://www.google.com", \ "http://www.naver.com", \ "http://www.daum.net"] queue = Queue.Queue() class CustomThread(threading.Thread): def __init__(self, queue): threading.Thread.__init__(self) self.queue = queue def run(self): while True: task_url = self.queue.get() start = time.time() page = urllib2.urlopen(task_url) end = time.time() print """%s elapsed %s (from %s)""" \ % (task_url, end - start, self.getName()) self.queue.task_done() def main(): for i in range(2): t = CustomThread(queue) t.daemon = True t.start() for task_url in urls: queue.put(task_url) queue.join() print "Ended" if __name__ == "__main__": main()
This is typical producer-consumer model using queue. We can use this model when we want to keep threads running on though tasks are consumed up(like threadpool). Otherwise, we can call join() for each thread instead of calling queue.join().
Thursday, August 16, 2012
Dustin Hyun at NHN Corporation.
I was interviewed to be posted on corporate blog of nhn(written in Korean).
http://naver_diary.blog.me/150144134830
NHN에서 가장 많은 사람은? 당연히 개발자입니다. NHN 직원 중 절반 이상이 개발자입니다. 게다가 인터넷 서비스에 필요한 소프트웨어는 워낙 다양하기 때문에, 개발자들이 담당하는 역할도 천차만별입니다. 이번 시리즈를 준비하면서 다양한 개발직군의 모습을 보여 드리고 싶었는데요. NHN PEOPLE 두 번째 주인공 현동석 차장은 그 좋은 예가 될 것 같...
http://naver_diary.blog.me/150144134830
NHN PEOPLE - 2. 개발자
NHN에서 가장 많은 사람은? 당연히 개발자입니다. NHN 직원 중 절반 이상이 개발자입니다. 게다가 인터넷 서비스에 필요한 소프트웨어는 워낙 다양하기 때문에, 개발자들이 담당하는 역할도 천차만별입니다. 이번 시리즈를 준비하면서 다양한 개발직군의 모습을 보여 드리고 싶었는데요. NHN PEOPLE 두 번째 주인공 현동석 차장은 그 좋은 예가 될 것 같...Friday, May 25, 2012
Good explanation on linux daemon.
I was programming a daemon invoked from a python script which is also invoked from a server that fork() .py when it gets a command through TCP connection.
TCP:Message => Server:fork() => python:os.system() => daemon(c++)
However, server couldn't return the message from python script even though the binary was demonized successfully(It was a zombie proccess).
I spent a lot of time to find for this. TT. I found that the daemon inherited all file descriptors from the server via .py script.
Now everything works find after closing all fds after being fork()ed.
Useful links:
http://www.enderunix.org/docs/eng/daemon.php
TCP:Message => Server:fork() => python:os.system() => daemon(c++)
However, server couldn't return the message from python script even though the binary was demonized successfully(It was a zombie proccess).
I spent a lot of time to find for this. TT. I found that the daemon inherited all file descriptors from the server via .py script.
Now everything works find after closing all fds after being fork()ed.
Useful links:
http://www.enderunix.org/docs/eng/daemon.php
Friday, June 24, 2011
Recording Desktop at Ubuntu
Very simple.
Record with gtk-RecordMyDeskTop. Outfile format will be .ogv
To convert ogv to avi,
> mencoder -idx out.ogv -ovc lavc -oac mp3lame -o out.avi
Done.
Record with gtk-RecordMyDeskTop. Outfile format will be .ogv
To convert ogv to avi,
> mencoder -idx out.ogv -ovc lavc -oac mp3lame -o out.avi
Done.
Monday, June 13, 2011
C++: Building custom vector class.
Making custom container class with iterator would be a good example for C++ beginner.
Vector.h
#ifndef VECTOR_H
#define VECTOR_H
#include <vector>
#include "VectorIterator.h"
class Vector {
public:
typedef VectorIterator iterator;
Vector(int size) { data_.resize(size); }
int size() const;
void push_back(const int val);
VectorIterator begin();
VectorIterator end();
int& operator[](const int& idx);
private:
std::vector<int> data_;
};
inline int &
Vector::operator[](const int& idx) {
return data_[idx];
}
inline int
Vector::size() const {
return data_.size();
}
inline void
Vector::push_back(const int val) {
data_.push_back(val);
return;
}
#endif /* VECTOR_H */
Vector.cpp
#include "Vector.h"
VectorIterator
Vector::begin() {
return VectorIterator(&data_);
}
VectorIterator
Vector::end() {
VectorIterator vec(&data_);
vec.setIndex(data_.size());
return vec;
}
VectorIterator.h
#ifndef VECTORITERATOR_H
#define VECTORITERATOR_H
#include <vector>
class VectorIterator {
public:
VectorIterator();
VectorIterator(std::vector<int> * data);
void setIndex(int v);
int operator*();
int operator++();
bool operator==(const VectorIterator& rhs) const;
bool operator!=(const VectorIterator& rhs) const;
private:
std::vector<int>* pvec_;
int index_;
};
inline int
VectorIterator::operator*()
{
return (*pvec_)[index_];
}
inline int
VectorIterator::operator++()
{
index_++;
return (*pvec_)[index_];
}
inline bool
VectorIterator::operator==(const VectorIterator& rhs) const
{
return (pvec_ == rhs.pvec_ && index_ == rhs.index_);
}
inline bool
VectorIterator::operator!=(const VectorIterator& rhs) const
{
return !(*this == rhs);
}
#endif /* VECTORITERATOR_H */
VectorIterator.cpp
#include "VectorIterator.h"
void
VectorIterator::setIndex(int v) {
index_ = v;
return;
}
VectorIterator::VectorIterator()
: pvec_(NULL), index_(0) {}
VectorIterator::VectorIterator(std::vector<int> * data)
: pvec_(data), index_(0) {}
main.cpp
#include <iostream>
#include "Vector.h"
int main()
{
int size = 10;
Vector vec(size);
for (int i = 0; i < vec.size(); i++)
vec[i] = 2 * i;
for (Vector::iterator iter = vec.begin();
iter != vec.end(); ++iter)
std::cout << *iter << std::endl;
return 0;
}
Thursday, June 9, 2011
making google preview

When user input query, thumbnail for each search result is gathered simultaneously. This works with render function of phantomjs(webkit based script binary). The image it made is saved with hashed url as a filename so that it would not render twice. And it also highlight with red box where the query appears in the page(You can see little tiny red bordered box in the thumbnail above, right?). Though it consumes lots of system resources, it works.
Friday, March 4, 2011
C++ pointer, reference - **, *&, &&, &*
Let's think about pointer and reference with - &&, &*, ** and *&
- int &&a;
ILLEGAL : '&&' is a comparison syntax, not a pointer nor reference thing. Pass. - int &*a;
ILLEGAL : (pointer-to-reference) Can't declare a pointer to int&. Reference is another name of an object(you can't set a pointer to a 'name'). - int **a;
pointer-to-pointer : You can use
value(**a), pointer address(*a) and pointer's pointer address(a). - int *&a;
reference-to-pointer : You can use
value(*a), pointer address(a) and pointer's pointer address(&a).
Get confused :) ?
Thursday, February 10, 2011
C++ Exception
Exception is consist of detection and handling.
When an exception happens, program stops, finds where to handle, handles exception, and resumes from where it handled an eception.
Class, integer or string can be an exception object to be thrown.
Throwing an exception is done by
Try always goes with catch.
Exception can be sent to upper routine after handling.
If no handler found, program ends with terminate().
Thinks
When a class constructor fails, only exception can make it known to the program.
Use of exception reduces 'if ... else ...' statements.
Level of exception handler in the program is where it knows the exception and the way to handle it.(In other words, it's good to propagate an exception to the upper routine when it's not adequate to handle it there.)
Exception is different from hardware exception like seg-fault. That means there's 'throw' codes in the program.
This kind of handling code of resource releasing is not that good.
Instead, resource alloc, release routine is good to be in the constructor, destructor code of the class("Resource aquisition is initialization" - Bjarne Stroustrup). "Because exception handling guarantees to call all destructors of local variables".
Standard exceptions.
Auto pointer.
When an exception happens, program stops, finds where to handle, handles exception, and resumes from where it handled an eception.
Class, integer or string can be an exception object to be thrown.
Throwing an exception is done by
throw exceptionObject;
Try always goes with catch.
try {
throw "happened!";
}
catch (const char *msg) {
}
catch (...)
{
// handles all exceptions.
}
Exception can be sent to upper routine after handling.
catch (...) {
// handles exception
...
throw; // propagates again for the other handler
}
If no handler found, program ends with terminate().
Thinks
When a class constructor fails, only exception can make it known to the program.
Use of exception reduces 'if ... else ...' statements.
// Before,
if (condition) {
// do something
}
else {
// handle by itself
}
// After,
check_condition(); // raise exception.
// do something
Level of exception handler in the program is where it knows the exception and the way to handle it.(In other words, it's good to propagate an exception to the upper routine when it's not adequate to handle it there.)
Exception is different from hardware exception like seg-fault. That means there's 'throw' codes in the program.
This kind of handling code of resource releasing is not that good.
// not a good example.
try {
// alloc something.
}
catch (...) {
// release them.
throw;
}
Instead, resource alloc, release routine is good to be in the constructor, destructor code of the class("Resource aquisition is initialization" - Bjarne Stroustrup). "Because exception handling guarantees to call all destructors of local variables".
Standard exceptions.
C++ offers 'exception' basic class. This class has a virtual function 'what()' which returns const char * so, we can know what's going on during an exception with this message(throw() means this function will not throw an exception).
class exception {public:virtual const char * what() const throw();...}
So if your code has a catch statement like below, it catches all kinds of standard exception which inherits from the exception class.
catch (const std::exception &ex) {std::cout << ex.what() << std::endl;}
Notes
Auto pointer.
#include <memory>
...
auto_ptrp(new AClass); // will be released automatically.
Wednesday, January 12, 2011
Tuesday, December 28, 2010
Python egg
Very good explanation on Python egg package
- http://mrtopf.de/blog/en/a-small-introduction-to-python-eggs/
Thursday, December 23, 2010
Strategy pattern implementation using member function pointer.
Strategy pattern is used when there are various ways to solve one problem. Normally each algorithm to solve problem is implemented as a class. And those classes are inherited from base class. However, it's also possible to implement those pattern using member function pointers though it looks a bit quirky like (instace.*instance.functionPointer)(...). :)
#include <iostream>
class Class {
public:
typedef enum OPERATION {
SUM = 0,
MUL
} operation;
Class();
int func(int a, int b, operation op);
int (Class::*fp[2])(int a, int b);
private:
int sum(int a, int b);
int mul(int a, int b);
};
Class::Class()
{
fp[SUM] = &Class::sum;
fp[MUL] = &Class::mul;
}
int
Class::func(int a, int b, Class::operation op)
{
return (this->*fp[op])(a, b);
}
int
Class::sum(int a, int b)
{
return a + b;
}
int
Class::mul(int a, int b)
{
return a * b;
}
int main()
{
Class c;
std::cout << c.func(2, 4, Class::SUM) << std::endl;
std::cout << (c.*c.fp[Class::MUL])(2, 4) << std::endl;
return 0;
}
#include <iostream>
class Class {
public:
typedef enum OPERATION {
SUM = 0,
MUL
} operation;
Class();
int func(int a, int b, operation op);
int (Class::*fp[2])(int a, int b);
private:
int sum(int a, int b);
int mul(int a, int b);
};
Class::Class()
{
fp[SUM] = &Class::sum;
fp[MUL] = &Class::mul;
}
int
Class::func(int a, int b, Class::operation op)
{
return (this->*fp[op])(a, b);
}
int
Class::sum(int a, int b)
{
return a + b;
}
int
Class::mul(int a, int b)
{
return a * b;
}
int main()
{
Class c;
std::cout << c.func(2, 4, Class::SUM) << std::endl;
std::cout << (c.*c.fp[Class::MUL])(2, 4) << std::endl;
return 0;
}
Tuesday, November 23, 2010
번역 완료 - HTML5 활용
Subscribe to:
Posts (Atom)

