As per keskiverto's link, in something like
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
class ComplexNumbers
{
public:
ComplexNumbers() :
real_(0),
imaginary_(0)
{
// Other stuff happens after direct initializer
instance_counter++;
}
static int instance_counter;
private:
double real_;
double imaginary_;
};
int ComplexNumbers::instance_counter = 0;
|
The real_ and imaginary_ variables are initialized first, before the constructor body. Static variables can't be default-initialized in this way.
You asked about that particular colon context, but I can think of a few more places where the colon is used in C++:
1. As a label, e.g.
after_loop:
in the following. Since the keyword
break
breaks you out of your current loop, some people have utilized
goto
and labels to break out of a nested loop.
Now this is not very readable and not recommended -- if possible try to redesign the function so that you can
return
out of a nested loop, or for readability set a flag to true, break out, and in the outer loop also break out if the flag had changed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
bool Complicated(int& answer)
{
bool found = false;
int possible_answer;
for (int i=1; i<=100000; ++i)
{
for (int j<=1; j<=100000; ++j
{
if ( possible_answer = WhatImLookingFor(i,j) != -1)
{
found = true;
goto after_loop;
}
}
}
after_loop:
// Additional processing within function
if (found && ThisAnswerIsGood(possible_answer))
{
answer = possible_answer;
return true;
}
answer = -1;
return false;
}
|
2. Ternary statements -- Something ? truecase : falsecase. Looks especially nice when assignment to a variable is involved.
This snippet
1 2 3 4 5 6 7 8 9
|
string s;
if ( IsDone() )
{
s = "done";
}
else
{
s = "not done";
}
|
can be rewritten as
string s = IsDone() ? "done" : "not done";
3. Switch statements. In some ways similar the colons in labels. I'm sure you've seen many colons in switch statements, which often have cases consisting of constants or enums:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
enum { RED, GREEN, BLUE };
void MyFunction(int i)
{
switch (i)
{
case RED:
myvar_ = "red";
break;
case GREEN:
myvar_ = "green";
break;
case BLUE:
myvar_ = "blue";
break;
default:
myvar_ = "";
break;
}
}
|
4. Marking access in classes/structs (public/private/protected):
1 2 3 4 5 6 7 8 9 10 11
|
class MyClass
{
public:
MyClass();
protected:
int share_this_with_children;
private:
int dont_touch_;
};
|