C++は、C言語の基本的な知識を持っている人が始めるのに適しています。
C++チュートリアル
名前空間とは
名前空間は、モジュール間の名前の衝突を解決するために使用されます。
#include <iostream>
using namespace std;
int main() {
cout<<"*******"<<endl;
cout<<"Hello World!"<<endl;
cout<<"*******"<<endl;
return 0;
}
ドメイン修飾子 :: を 使うことで、ケースバイケースで数を指定することもできます。
#include <iostream>
//using namespace std;
int main() {
std::cout<<"*******"<<std::endl;
std::cout<<"Hello World!"<<std::endl;
std::cout<<"*******"<<std::endl;
return 0;
}
入力と出力
- coutは<< />付き
- cin with >>はキーボードからの入力を読み込むことを意味します。
#include <iostream>
using namespace std;
int main() {
int a;
cout<<"input string"<<endl;
cin>>a;
cout<<"get string is "<<a<<endl;
return 0;
}
出力は
input string
123
get string is 123
基本的なデータ型
- int、char、float、doubleは、それぞれプラスチック、文字、単精度、倍精度を表します。
- Cよりも、ブール型boolがあり、1は真、0は偽を意味します。
#include <iostream>
using namespace std;
int main() {
int id;
char sex;
double score1 = 0, score2 = 0, score3 = 0;
bool isNO1;
cout << "please input ID, 'M' or 'W', score1, score2, score3" << endl;
cin >> id >> sex >> score1 >> score2 >> score3;
isNO1 = score1 > 12;
cout << "ID=" << id << ",sex=" << sex << ",total=" << score1 + score2 + score3 <<",isNo1="<<isNO1<<endl;
return 0;
}
演算子と式
- 算術演算子 +, -, *, %。
- 自己増加・自己減少演算子 ++, --。
- 代入演算子 =
- <、>関係演算子 >、=、<=、!=, ==
- 論理演算子 && || !
/**
* 数値が"水仙の数" "水仙の数"は、まず3桁の数字である。
* 次に、その数字の3乗和は数字そのものに等しい。例えば、371は"水仙の数" +7^3+1^3.
* @return
*/
int main() {
int a, ge, shi, bai;
cout << "input num >100" << endl;
cin >> a;
ge = a % 10;
shi = a % 100 / 10;
bai = a / 100;
cout << "ge=" << ge << ",shi=" << shi << ",bai=" << bai << endl;
if ((ge * ge * ge + shi * shi * shi + bai * bai * bai) == a) {
cout << 1 << endl;
} else {
cout << 0 << endl;
}
return 0;
}
出力は
input num >
ge=9,shi=8,bai=7
ループ構造
forループ、do whileループ、whileループ、breakとcontinueの組み合わせ
#include <iostream>
using namespace std;
int main() {
int a,b;
while (cin>>a>>b){
cout<<a+b<<endl;
}
return 0;
}
cinはistreamストリーム・オブジェクトを返すので、何度でもトラバースすることができます。
1 2
3
4 5
9
7 8
15
...
関数呼び出し
#include <iostream>
#include <cstring>
using namespace std;
/**
* 文字列の反転 123abc---->cba321
* @param a オリジナルの文字列
* @param b 反転文字列
* @return
*/
int reverse(char a[], char b[]) {
int n = strlen(a);
int i = 0;
while (a[i] != '\0') {
b[n - i - 1] = a[i];
i++;
}
b[n] = '\0';
return 0;
}
int main() {
char a;
char b;
cin >> a;
reverse(a, b);
cout << b << endl;
return 0;
}
デフォルトの形式パラメータを持つ関数
形式パラメータは、デフォルトの関数
int main() {
cout<<add()<<endl;
cout<<add(1,9)<<endl;
cout<<add(5)<<endl;
return 0;
}
オーバーロードされた関数
Javaと同様に、C++の関数もオーバーロードすることができます。
int add(int a = 2, int b = 6) {
return a + b;
}
double add(double a = 1, double b = 5) {
return a + b;
}
関数テンプレート
javaのジェネリックスと同様に、テンプレートで定義されます。
#include <iostream>
using namespace std;
template<class T1, class T2>
T1 add(T1 a, T2 b) {
cout << sizeof(a) << " , " << sizeof(b) << "\t";
return a + b;
}
int main() {
cout << add(1, 5) << endl;
cout << add(1.2, 1.5) << endl;
cout << add('A', 2) << endl;
return 0;
}
4 , 4 6 8 , 8 2.7 1 , 4 Cインライン関数
関数のメソッドスタック呼び出し時に、呼び出しの時点で関数を完全に展開することで、スペースと時間を節約します。
inline int Max(int a, int b) {
return a > b ? a : b;
}
int main() {
cout << Max(1, 2) << endl;
cout << Max(6, 5) << endl;
return 0;
}
クラスとオブジェクト
ドメイン修飾子
クラス名の外にあるメソッドは、ドメイン修飾子 :: で定義されますが、最初にクラス内で関数名を定義する必要があります。
class Person {
public:
int num;
char name;
double score;
int print();
};
int Person::print() {
cout << num << " " << name << " " << score << endl;
return 0;
}
と同じです。
class Person {
public:
int num;
char name;
double score;
int print() {
cout << num << " " << name << " " << score << endl;
return 0;
}
};
コンストラクタ
C++ にはデフォルトのコンストラクタがありますが、カスタマイズすることもできます。
class Student {
private:
char name;
int num;
double score;
public:
Student(char *n, int num1, double score1);
void print();
};
Student::Student(char *n, int num1, double score1) {
strcpy(name, n);
num = num1;
score = score1;
}
void Student::print() {
cout<<name<<" "<<num<<" "<<score<<endl;
}
int main() {
Student A("xiaoming", );
A.print();
return 0;
}
デストラクタ
- 関数の前に ~ を追加します。
- デフォルトの関数はカスタマイズすることもでき、オブジェクトが破棄されるときに呼び出されます。
class Student {
private:
char name;
int num;
double score;
public:
Student(char *n, int num1, double score1);
~Student();
void print();
};
Student::Student(char *n, int num1, double score1) {
strcpy(name, n);
num = num1;
score = score1;
cout << name << " " << num << " " << score << " constructor" << endl;
}
Student::~Student() {
cout << name << " " << num << " " << score << " destructor" << endl;
}
void Student::print() {
cout << name << " " << num << " " << score << endl;
}
int main() {
Student A("this is A", );
Student B("this is B", );
return 0;
}
this is A 1 98.7 constructor
this is B 2 98.6 constructor
this is B 2 98.6 destructor
this is A 1 98.7 destructor
BのデストラクタはAの前に呼ばれます。ローカル変数はスタック上にあるので、「先入れ先出し」の原則に従います。
コピーコンストラクタ
オブジェクト参照を関数のパラメータとして受け取ります。
class Circle {
private:
double R;
public:
Circle(double R);
Circle(Circle &circle);
};
Circle::Circle(double R) {
cout<<"constructor"<<endl;
this->R = R;
}
Circle::Circle(Circle &circle) {
cout<<"copy constructor"<<endl;
this->R = circle.R;
}
int main() {
Circle A(2);
Circle B(A);
return 0;
}
デフォルトのコピーコンストラクタはシャローコピーで、カスタムのものはディープコピーです。 シャローコピーは値を変更し、ディープコピーはメモリアドレスを変更します。
フレンドリー関数
このクラスの関数に他の関数からアクセスしたい場合は、friend を使ってその関数を friend としてマークすることができます。
class Point {
private:
double x;
double y;
public:
Point(double x, double y) {
this->x = x;
this->y = y;
}
friend double getD(Point &a, Point &b);
};
double getD(Point &a, Point &b) {
double xx = a.x - b.x;
double yy = a.y - b.y;
return sqrt(xx * xx + yy * yy);
}
int main() {
Point A(1.0, 2.0);
Point B(2.0, 3.0);
double l = getD(A, B);
cout<<l<<endl;
return 0;
}
friend をつけないと、main 関数の中で getD 関数を呼び出すことができません。
フレンド
クラスBがクラスAのフレンドとして定義されている場合、BはAのプライベート変数にアクセスできます。
class Point {
private:
double x;
double y;
public:
Point(double x, double y) {
this->x = x;
this->y = y;
}
friend class Tool;
};
class Tool {
public:
double getD(Point &point) {
double l = sqrt(point.x * point.x + point.y * point.y);
cout<<l<<endl;
return l;
}
};
int main() {
Point C(1.0, 2.0);
Tool tool;
tool.getD(C);
return 0;
}
定数
I.定数データ・メンバ
- 例えば、int h は const int h または int const h と表示されます。
- 定数メンバ変数は、コンストラクタでデフォルト値を指定する必要があります。
Clock(int a) : h(a){
cout<<"constructor"<<endl;
}
- static で指定した const は、クラスの外で代入する必要があります。
class Clock{
private:
const int h;
const int m;
int const s;
static const int x;
public:
Clock(int a,int b, int c) : h(a), m(b), s(c) {
cout<<"constructor"<<endl;
}
int getX() {
cout<<x<<endl;
return x;
}
};
const int Clock::x = 99;
int main() {
Clock A(1, 2, 3);
A.getX();
return 0;
}
II.定数オブジェクト
コンスタントオブジェクトもまた、ライフサイクル中は不変であり、コンストラクタを通して値を代入することができます。
const Clock A(1, 2, 3);
//A.getX(); この行はエラーを報告する
III.定数関数
- 定数関数はメンバ変数にのみアクセスでき、書き換えることはできません。
int getX() const {
//x=66;
cout << x << endl;
return x;
}
継承と派生
継承
- 継承は親クラス、派生は子クラスです。
- 継承はコロン
class Person {
protected:
char name;
int sex;
public:
void setName(char *n) {
strcpy(name, n);
}
};
class Student: public Person {
public:
void setSex(int s) {
this->sex = s;
}
void getInfo() {
cout<<name<<" "<<sex<<endl;
}
};
int main() {
Student A;
A.setName("tanakasan");
A.setSex(0);
A.getInfo();
return 0;
}
派生クラスのコンストラクタ
まず親クラスのコンストラクタを呼び出し、次に子クラスのコンストラクタを呼び出します。
#include <iostream>
#include <cstring>
using namespace std;
class Person{
public:
char name;
int sex;
public:
Person(char *name,int sex) {
strcpy(this->name, name);
this->sex = sex;
cout<<"Person contructor"<<endl;
}
};
class Student: public Person {
public:
Student(char *n, int o) : Person(n, o) {
cout<<"Student contructor"<<endl;
}
};
int main() {
Student A("xiaoming", 1);
return 0;
}
スタックの先入れ先出しの原則により、デストラクタは逆に呼ばれます。つまり、子クラスが最初に呼ばれ、次に親クラスが呼ばれます。
仮想基底クラス
C++ では多重継承が可能ですが、複数の親クラスから継承する場合、親クラスに virtual を追加する必要があります。
class A {
public:
int key;
};
class B: virtual public A {
};
class C: virtual public A {
};
class D : public B, public C {
};
int main() {
D d1;
d1.key = 6;
return 0;
}
仮想関数
仮想関数はポリモーフィックな問題を解決するために使用されます。
class Point {
private:
int x;
int y;
public:
Point(int x = 0, int y = 0) {
this->x = x;
this->y = y;
}
virtual double area() {
return 0;
}
};
class Circle: public Point {
private:
int x1;
int x2;
int x3;
public:
Circle(int d,int e, int f) {
this ->x1 = d;
x2 = e;
x3 = f;
}
double area() {
return 3.14 * x1 * x2;
}
};
int main() {
Point A(10, 11);
cout<<A.area()<<endl;
Circle B(2, 6, 7);
cout<<B.area()<<endl;
Point *D;
D = &B;
cout<<D->area()<<endl;
Point &p = B;
cout<<p.area()<<endl;
return 0;
}
仮想デストラクタ関数
基底クラスのデストラクタにダミー関数を追加することで、そのサブクラスのダミー関数も呼び出すことができます。





