Function templates
func_temp.cpp
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 | // function template
#include <iostream>
using namespace std;
template <class T>
T GetMax(T a, T b){
T result;
result = (a > b) ? a : b;
return result;
}
int main(){
int i1 = 10, i2 = 6;
int i_comp;
float l1 = 10.5, l2 = 6.5;
float l_comp;
i_comp = GetMax<int>(i1, i2);
l_comp = GetMax<float>(l1, l2);
cout << i_comp << endl;
cout << l_comp << endl;
}
|
func_temp.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./func_temp
10
10.5
func_temp2.cpp
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 | // function template 2
#include <iostream>
using namespace std;
template <class T>
T GetMax(T a, T b){
return (a > b ? a : b);
}
int main(){
int i1 = 10, i2 = 6;
int i_comp;
float l1 = 10.5, l2 = 6.5;
float l_comp;
i_comp = GetMax(i1, i2);
l_comp = GetMax(l1, l2);
cout << i_comp << endl;
cout << l_comp << endl;
return 0;
}
|
func_temp2.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./func_temp2
10
10.5
Class templates
class_temp.cpp
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 27 28 29 30 31 | // class templates
#include <iostream>
using namespace std;
template <class T>
class mypair{
T a;
T b;
public:
mypair(T fs, T se){
a = fs;
b = se;
}
T getmax();
};
template <class T>
T mypair<T>::getmax(){
T retval;
retval = (a > b? a : b);
return retval;
}
int main(){
mypair <int> myobject(100, 75);
cout << myobject.getmax() << endl;
return 0;
}
|
class_temp.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./class_temp
100
Template specialization
temp_spec.cpp
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | // template specialization
#include <iostream>
using namespace std;
// class template
template <class T>
class mycontainer{
T element;
public:
mycontainer(T arg){
element = arg;
}
T increase(){
return element++;
}
};
// clas template specialization
template <>
class mycontainer <char>{
char element;
public:
mycontainer(char arg){
element = arg;
}
char uppercase(){
if( (element >= 'a') && (element <= 'z') )
element += 'A' - 'a';
return element;
}
};
int main(){
mycontainer<int> myint(7);
mycontainer<char> mychar('j');
cout << myint.increase() << endl;
cout << mychar.uppercase() << endl;
return 0;
}
|
temp_spec.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./temp_spec
7
J
Non-type parameters for templates
seqtemp.cpp
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 27 28 29 30 31 32 33 34 35 | // sequence template
#include <iostream>
using namespace std;
template <class T, int N>
class mysequence{
T memblock[N];
public:
void setmember(int x, T value);
T getmember(int x);
};
template <class T, int N>
void mysequence<T, N>::setmember(int x, T value){
memblock[x] = value;
}
template <class T, int N>
T mysequence<T, N>::getmember(int x){
return memblock[x];
}
int main(){
mysequence<int, 5> myints;
mysequence<double, 5> myfloats;
myints.setmember(0, 100); // index:0, value:100
myfloats.setmember(3, 3.14159); // index:3, value: 3.14159
cout << myints.getmember(0) << endl;
cout << myfloats.getmember(3) << endl;
return 0;
}
|
seqtemp.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./seqtemp
100
3.14159
Templates and multiple-file projects
Namespaces
namespaces.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // namespaces
#include <iostream>
using namespace std;
namespace first{
int var = 5;
}
namespace second{
double var = 5.5;
}
int main(){
cout << "first::var is " << first::var << endl;
cout << "second::var is " << second::var << endl;
return 0;
}
|
namespaces.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./namespaces
first::var is 5
second::var is 5.5
using
using.cpp
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 | // using
#include <iostream>
using namespace std;
namespace first{
int x = 5;
int y = 10;
}
namespace second{
double x = 3.14;
double y = 6.28;
}
int main(){
using first::x;
using second::y;
cout << x << endl;
cout << y << endl;
cout << "first::y is " << first::y << endl;
cout << "second::x is " << second::x << endl;
return 0;
}
|
using.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./using
5
6.28
first::y is 10
second::x is 3.14
using2.cpp
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 | // using2
#include <iostream>
using namespace std;
namespace first{
int x = 5;
int y = 10;
}
namespace second{
double x = 3.14;
double y = 6.28;
}
int main(){
using namespace first;
cout << x << endl;
cout << y << endl;
cout << "second::x is " << second::x << endl;
cout << "second::y is " << second::y << endl;
return 0;
}
|
using2.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./using2
5
10
second::x is 3.14
second::y is 6.28
using3.cpp
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 | // using3 namespace example
#include <iostream>
using namespace std;
namespace first{
int x = 5;
}
namespace second{
double x = 3.14;
}
int main(){
{
using namespace first;
cout << x << endl;
}
{
using namespace second;
cout << x << endl;
}
return 0;
}
|
using3.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./using3
5
3.14
Namespace alias
We can declare alternate namef for exisitng namespaces according following format:
namespace new_name = current_name;
Namespace std
All the files in the c++ standard library declare all of its entities within the std namespace. That is why we have generally included the using namespace std; statement in all programs that used any entity defined in iostream.
Exceptions
exception.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 | // exception
#include <iostream>
using namespace std;
int main(){
try{
throw 20;
}
catch(int e){
cout << "An exception occurred. Exception Nr. " << e << endl;
}
}
|
exception.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./exception
An exception occurred. Exception Nr. 20
Standard exceptions
exception2.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // standard exceptions
#include <iostream>
#include <exception>
using namespace std;
class myexception: public exception{
virtual const char* what() const throw(){
return "My exception happened";
}
}myex;
int main(){
try{
throw myex;
}
catch(exception& e){
cout << e.what() << endl;
}
}
|
exception2.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./exception2
My exception happened
Explicit conversion
type_casting.cpp
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 27 28 29 30 | // class type-casting
#include <iostream>
using namespace std;
class CDummy{
float i, j;
};
class CAddition{
int x, y;
public:
CAddition(int a, int b){
x = a;
y = b;
}
int result(){
return x + y;
}
};
int main(){
CDummy d;
CAddition *padd;
padd = (CAddition *)&d;
cout << padd->result() << endl;
return 0;
}
|
type_casting.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./type_casting
0
dyna_cast.cpp
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 27 28 29 30 31 32 33 | // dynamic_cast
#include <iostream>
#include <exception>
using namespace std;
class CBase{
virtual void dummy(){}
};
class CDerived: public CBase{
int a;
};
int main(){
try{
CBase *pba = new CDerived;
CBase *pbb = new CBase;
CDerived *pd;
pd = dynamic_cast<CDerived *>(pba);
if(pd == 0)
cout << "Null pointer on first type-cast" << endl;
pd = dynamic_cast<CDerived *>(pbb);
if(pd == 0)
cout << "Null pointer on second type-cast" << endl;
}catch(exception& e){
cout << "Exception: " << e.what();
}
return 0;
}
|
dyna_cast.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./dyna_cast
Null pointer on second type-cast
const_cast
const_cast.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // const_cast
#include <iostream>
#include <exception>
using namespace std;
void print(char *str){
cout << str << endl;
}
int main(){
const char *c = "sample text";
print( const_cast<char *>(c) );
return 0;
}
|
const_cast.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./const_cast
sample text
typeid
typeid.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // typeid
#include <iostream>
#include <typeinfo>
using namespace std;
int main(){
int *a, b;
a = 0;
b = 0;
if( typeid(a) != typeid(b) ){
cout << "a and b are different types:" << endl;
cout << "a is: " << typeid(a).name() << endl;
cout << "b is: " << typeid(b).name() << endl;
}
return 0;
}
|
typeid.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./typeid
a and b are different types:
a is: Pi
b is: i
typeid2.cpp
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 27 28 29 | // typeid, polymorphic class
#include <iostream>
#include <typeinfo>
#include <exception>
using namespace std;
class CBase{
virtual void f(){}
};
class CDerived: public CBase{};
int main(){
try{
CBase *a = new CBase;
CBase *b = new CDerived;
cout << "a is: " << typeid(a).name() << endl;
cout << "b is: " << typeid(b).name() << endl;
cout << "*a is: " << typeid(*a).name() << endl;
cout << "*b is: " << typeid(*b).name() << endl;
}catch(exception& e){
cout << "Exception: " << e.what() << endl;
}
return 0;
}
|
typeid2.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./typeid2
a is: P5CBase
b is: P5CBase
*a is: 5CBase
*b is: 8CDerived
macro definitions (#define, #undef)
macro.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // function macro
#include <iostream>
using namespace std;
#define getmax(a, b) ( (a) > (b) ? (a) : (b) )
int main(){
int x = 5;
int y;
y = getmax(x, 2);
cout << y << endl;
cout << getmax(7, x) << endl;
cout << getmax(7.2, 4.3) << endl;
cout << getmax(7.2, 8) << endl;
return 0;
}
|
macro.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./macro
5
7
7.2
8
Predefined macro names
predefined.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // standard macro names
#include <iostream>
using namespace std;
int main(){
cout << "This is the line number: " << __LINE__ << endl;
cout << "of file: " << __FILE__ << endl;
cout << "Its compilation began: " << __DATE__ << endl;
cout << "at: " << __TIME__ << endl;
cout << "The compiler gives a __cplusplus value of: " << __cplusplus << endl;
return 0;
}
|
predefined.cpp の実行結果は:
[cactus:~/code_c++/cpp_tuts]% ./predefined
This is the line number: 7
of file: predefined.cpp
Its compilation began: Sep 22 2010
at: 19:35:27
The compiler gives a __cplusplus value of: 1