C++ is a very complicated language. Learning it thoroughly will take years. You must understand this properly.
First book on C++ should be Thinking in C++. This is easy to get as its free. The only problem with this book is it doesn't tell you how to create abstractions in C++.
But learning a programming language is like learning to speak. First you learn to speak and then make it proper by learning the rules of language. So you must program also. Thinking in C++ doesn't give you that idea. So you must program.
In my experience people find operator overloading as tough part.
Why its tough? I think because of its syntax? Its hard to remember the rules
So when you learn C++ you must program some data structures in it. (For example try implenting link list/tree in C++).(Caution: This will be tough if you are programming in C++ for first time).
It will help you to think logically using C++ as a a language.
A gentle test in C++ to see if you are level 0 inside C++ lanaguage.
Can you write the code of the following:
1. Implement link list in the C++.
2. Implement binary search tree in C++.
3. Implement binary search in C++.
//Design problems.
1. Write a singleton class.
2. Write a factory class.
See if you can spot some errors:
1.
class A
{
public:
virtual void f(){}
};
class B : public A
{
public:
virtual void f(){}
};
void g(A * p)
{
memset(p,0,sizeof(A));
p->f();
}
Any error has been observed?
2. Write a code which stops object from being copied.
(Hint: Inside member functions also)
3. Write a code which stops the object construction if an event has occured in the network.
(Hint: You can know about the event from a function which is given. But there shouldn't be any leak in code).
More about this in next blog.
Sunday, March 28, 2010
Sunday, March 21, 2010
Generic Programming in C++
Last week I was working on how does the templates can solve some problems which can avoid to write repeated code. Basically I was trying to apply principles which Generative Programming tells (In a very beautiful way indeed).
One of the few principles it states that about domain engineering. How for a particular domain, code can be inside common repository.
The easy part is code can be written prety easily using templates. But all this depends on projects that you are doing. Most of the time code gets written based on requirements of a concrete product. I feel in those environments writing domain based code is not possible. (Like STL can't be written with a particular project in time).
To write the code which can be used in a domain there should be two approched one is vertical and horizontol.
Vertical approach is required when code is written for a product and in those places generalization can be done. There you'll see the plethora of libraries being written which solve various purpose.
More difficult is to use horizontol approach. Here the true generic programming takes place.
I think this is similar to data mining: In data mining data is analyzed to get the patterns hidden in data. Similarly for "code mining" its required to do code analysis and find patterns in code and help in writing code which can be used across similar product lines.
Take an example: Take a model of trying to route a message based on a configured policy.
Now for a router (IP Layer) this could be based on IP tables for an HTTP server it should be based on DNS. (Network Layer)
If you see the code is almost easy and should be written like below so that each prodfuct can be used it independently.
template typename Message,
class MessageRouter
{
bool operator()(Message & message,RoutingPolicy & routingPolicy)
{
RoutingPolicy::Iterator itr = routingPolicy.getFirstPolicy();
for (;itr != routingPolicy.end();++itr)
{
if (itr->route(message))
{
return true;
}
}
return false;
}
};
This code is a simplification. But we can see the principles here. The same code code is repeated across the IP layer and application layer across TCP/IP leyer.
One of the few principles it states that about domain engineering. How for a particular domain, code can be inside common repository.
The easy part is code can be written prety easily using templates. But all this depends on projects that you are doing. Most of the time code gets written based on requirements of a concrete product. I feel in those environments writing domain based code is not possible. (Like STL can't be written with a particular project in time).
To write the code which can be used in a domain there should be two approched one is vertical and horizontol.
Vertical approach is required when code is written for a product and in those places generalization can be done. There you'll see the plethora of libraries being written which solve various purpose.
More difficult is to use horizontol approach. Here the true generic programming takes place.
I think this is similar to data mining: In data mining data is analyzed to get the patterns hidden in data. Similarly for "code mining" its required to do code analysis and find patterns in code and help in writing code which can be used across similar product lines.
Take an example: Take a model of trying to route a message based on a configured policy.
Now for a router (IP Layer) this could be based on IP tables for an HTTP server it should be based on DNS. (Network Layer)
If you see the code is almost easy and should be written like below so that each prodfuct can be used it independently.
template
class MessageRouter
{
bool operator()(Message & message,RoutingPolicy & routingPolicy)
{
RoutingPolicy::Iterator itr = routingPolicy.getFirstPolicy();
for (;itr != routingPolicy.end();++itr)
{
if (itr->route(message))
{
return true;
}
}
return false;
}
};
This code is a simplification. But we can see the principles here. The same code code is repeated across the IP layer and application layer across TCP/IP leyer.
Sunday, March 7, 2010
Why C++ STL is bad for interfaces design?
Let me correct myself and some disclaimers.
This is not a critique of STLs but how bad use can turn this into nightmare.
STL is one of best things to happen for C++.
It allows rapid creation of code (almost like interprted language). But there are some inherent problems here.
(Though I don't know how to overcome it).
For example take STL string. Default allocator moves to new but I can tweak it to customized allocator. But consider I want to code like below:
void fun()
{
char buf[128] = "test";
manipulate(buf,128);
}
Now manipuate is a library function which doesn't takes string. What to do? Well I think the usual answer is library design is wrong? Change the library to accept string like below.
Well this is disater. The code that was mainpualting data structures on stack has suddenty moved on heap.
void mainputae(std::string & str);
Now try to change default allocator. Will it work.
Something like below:
void fun()
{
std::string<....,my_alloctor> str;
manipuate(*((std::string *) (&str)));
}
This also doesn't work. Since the allocator function is like below:
void * p = allocator::allocate(size);
This code is inside library. Inside the libtary the default allocator is still default so no use.
Actually STL are not meant for interfaces. Interfaces are designed so as to hide implementaion details and STL philosphy is not for that.
STL aim to provide generic algorithm and express is as type independent and key decisisions can be tuned as per details (memory allocation etc.) But tuning it to different types can lead to different data types. Hence the type is not completely defined.
Don't use STL for interfaces. (library design and you want to give library with simple .h types).
More about this in next post.
This is not a critique of STLs but how bad use can turn this into nightmare.
STL is one of best things to happen for C++.
It allows rapid creation of code (almost like interprted language). But there are some inherent problems here.
(Though I don't know how to overcome it).
For example take STL string. Default allocator moves to new but I can tweak it to customized allocator. But consider I want to code like below:
void fun()
{
char buf[128] = "test";
manipulate(buf,128);
}
Now manipuate is a library function which doesn't takes string. What to do? Well I think the usual answer is library design is wrong? Change the library to accept string like below.
Well this is disater. The code that was mainpualting data structures on stack has suddenty moved on heap.
void mainputae(std::string & str);
Now try to change default allocator. Will it work.
Something like below:
void fun()
{
std::string<....,my_alloctor> str;
manipuate(*((std::string *) (&str)));
}
This also doesn't work. Since the allocator function is like below:
void * p = allocator::allocate(size);
This code is inside library. Inside the libtary the default allocator is still default so no use.
Actually STL are not meant for interfaces. Interfaces are designed so as to hide implementaion details and STL philosphy is not for that.
STL aim to provide generic algorithm and express is as type independent and key decisisions can be tuned as per details (memory allocation etc.) But tuning it to different types can lead to different data types. Hence the type is not completely defined.
Don't use STL for interfaces. (library design and you want to give library with simple .h types).
More about this in next post.
Subscribe to:
Posts (Atom)