Most programers already have heard of it: There will be a new C++ ISO standard. It's in the making for quite some time now and compiler vendors already have implemented a lot of the features. It's commonly refered to as C++0x as people expected it to appear somewhere in 200x. Now it seems to become C++11, maybe C++12.
The changes are huge and looking at C++0x source code is like looking at a new language. It has both, new core language features and useful additions to the STL. In this post I'll introduce the feature of which I think that they will change the way C++ is used the most.
shared_ptr
shared_ptr
is an addition to the STL. It's a template class std::shared_ptr<T>
that implements
a reference counting pointer. Reference counting is a commonly known technique to C++ programmers and every
big codebase seems to have it's own implementation. They are also refered to as smart pointers.
The idea is simple: Instead of using raw pointers,
you pass the pointer into an object that overloads the *
and ->
operators so you can use
the object like a pointer. But additionally the object has a reference counter attached. Every
time you make a copy of that pointer object, the reference counter is increased. Uppon destruction,
the reference counter is decreased. If the reference counter goes down to 0, delete
is called.
Now the big advantage of having this in the STL means, that we can easily pass shared_ptr
in
interfaces.
Constructing shared_ptr
works like this:
#include <string>
#include <iostream>
#include <memory>
using namespace std;
int main(int, char**) {
shared_ptr<string> hello = shared_ptr<string>(new string("Hello World!"));
cout << *hello << endl;
return 0;
}
As you can see, there is no delete
. Usually this was a memory leak, but shared_ptr
will call
delete
for us. Common shared_ptr
implementations create an internal refcounter object on the
heap, so you will have 2 new
calls. Using the make_shared
template function can even
eliminate that and it's also shorter:
shared_ptr<string> hello = make_shared<string>("Hello World!");
You can pass around copies of hello
as you like, the refcounter will make sure it stays alive
as long as needed. Using shared_ptr
almost feels like garbage collection in C++. There
is one situation where reference counting fails: cycles. Think of a tree where parents know
their children and children know their parents. If you use shared_ptr
for both, forward and backward
links, you have a strong cycle and the refcounters will never go down to 0.
That's what weak_ptr
is for. You can make a weak_ptr
from a shared_ptr
. weak_ptr
get's notified
when the object it points to is destructed, so you won't get dangling pointers.
To access an object behind a weak_ptr
, you have to call lock()
on it. This will return a shared_ptr
.
My prediction is, that C++ libraries will soon start to use smart pointers extensively
and that will make C++ a better language.
If you want to learn more about smart pointers I can suggest the "Advanced STL" video lecture series by Stephan T. Lavavej on channel 9 . In part 3 he discusses everything about smart pointers.
auto
The auto
keyword is a new core language feature. It implements L-value type inference which is an
idea that most prominently is used in the Go language. In any assignment statement, there is an L-value
which is on the left side of the =
operator and an R-value (on the right side) which is the result
of an evaluated expression.
The R-value already has a strict type. When the L-value is a definition of a new variable, most of the time
you want it to have the type of the R-value. And since your compiler already knows that type, you can now
just tell it to use it:
auto hello = make_shared<string>("Hello World!");
hello
now has exactly the type std::shared_ptr<std::string>
. This might not seem to be
that important, but it greatly improves readability and coding speed in C++.
lambdas
In one of my last posts, I explained why the STL algorithms are decoupled from the containers they work on.
Now some of these algorithms, most prominently for_each
, require a function that will be used / applied uppon
the elements in the container. Modern dynamic languages like python long support functions as arguments, not to
mention functional languages.
C++03 did too, but the syntax was verbose. You could either pass a function pointer to a real function or implement
a callable function object (an object which has the ()
operator overloaded). Both were to complicated
and it was much easier to write a simple for
loop then to use for_each
. Now lambda expressions change that.
Take a look at this simple example:
vector<int> a_list;
for_each(a_list.begin(); a_list.end();
[](int x) { cout << x << endl; }
);
There is a lot more to lambdas, which I haven't even fully explored myself. E.g. using notations like [&]
or [=]
you can access the variable in the lambdas scope. You can read some more in
the wikipedia section about C++0x lambdas.
Lambdas will greatly increase the power and expressiveness of the language and will help improve the
functional style parts of C++.
function / bind
A std::function
is a typed callable object. It is typed on it's inputs and outputs and can be constructed from
a variety of constructs: raw function pointers, function objects, lambdas and binds.
Using std::function
it is easy to setup callbacks / signaling mechanisms in a typesafe C++ manner.
The classic example is a button onClick event:
class Button {
public:
void setOnClickEvent(std::function<void (void)> event) {
onClickEvent = event;
}
private:
void performOnClick() {
if(onClickEvent) {
onClickEvent();
}
}
std::function<void (void)> onClickEvent;
};
The std::bind
is a first order function object -- a function that has some arguments saturated, while others are left to be filled.
It looks like this:
void repeatedBeep(unsigned int x) {
for(unsigned int i=0; i<x; ++i) {
//...
}
}
int main(int, char**) {
Button button;
button.setOnClick( std::bind(repeatedBeep, 42) );
//...
}
Arguments in a std::bind
can also be other function objects which then results in a higher order function object. Wheeee... functional
programming in C++ :)
Admitted, you can do lot's of stupid stuff with binds and functions (and lambdas), exspecially if your arguments go out of scope where
you have passed references. But as always: C++ assumes the intelligent programmer. ;)
I guess when C++0x is in all stable mainstream compilers, we will see a new generation of GUI libraries which will make good use of these
facilities.
There is a lot more to C++0x, but most of them are details which make a difference for the hard-core library implementer. The features above are what I think will influence our every day code and architecture. And I don't know what you think, but I'm pretty excited about these new features.
A while ago I have found an interview with Herb Sutter ( this one on channel 9 ) where he was talking about the upcoming C++ standard (C++0x or C++11). There was one sentence in that Interview, that didn't seem that much important, but I have found it very true and it constantly comes back in my mind: It's important to get exposed to other languages. (at 18:00 in the video)
And it really is important: If you keep sticking your head deeper and deeper into one single language, you tend to forget why you do things the way you do. But at the moment you switch languages, you have to start thinking again. What's the right way to express what you want to do? Doing that, makes you a better programmer (of course you should always do that in your native language, as well).
I just noticed this when I had to do some Java again. Java removes some features from C++, that allow you to do stupid stuff and adds some features that encourage you to do good stuff. You can learn from Java that maybe you shouldn't do everything you can do. Or take Python: Pythons standard libraries is once of the best I have seen. Everything is where you intuitively expect it to be. Also, in Python there are simple free functions that are not part of any class (but part of a package/module/namespace) and that happens to provide much of the simplicity of pythons standard library. You can learn from Python how good libraries should look like and that not everything is a class.
So, next time you have an itch and need to create something, choose a new language. Even if it slows you down, take the time and your motivation to try out ... maybe ... Ruby, Go, Scala, C++0x or even Haskel. It will make you a better programmer.
Social networks are a good thing: People can connect, communicate and share. I think the Internet and within it, the social networks, will raise a whole generation of young people who will have learned to apreciate different cultures and people from around the world.
But most of these social networks, as much as they do good, they also violate your privacy through a very clever economic and technical measure: The Like! Button.
Content producers profit from putting such buttons on their pages because it increases their audience. Users profit from it because they can share stuff more easily. And the button providers profit from it because they can track where you go, what you look at and provide targeted advertising.
Now targeted advertising and profiling is not necessarily a problem. It only becomes a problem when you can't control your profile anymore. And that is what has happened with those Like buttons: They are everywhere and you cannot opt out. Or can you?
Yes you can, even with Chromium. I am currently trying out two Chromium extensions: Ghostery and Disconnect.
They both do a similar job: They block those tracking web bugs and like buttons. Unlike the popular Firfox ShareMeNot plugin they completely remove the buttons and thus remove function. But I can accept that and share manually.
Yay, looks like wiki2beamer is mentioned in the 2011/08 issue of the german print magazine "Linux Magazin" (thanks for the hint to sping). According to this content overview it's only a small "Tool Tips" section. But hey, it's print!
There seems to be no free online version of the article so I guess I'll get a copy at the kiosk.
Do you want an invite to Google+? Just drop me a line.