C++ function, class


🔑n.関数


•関数は、操作を実行した後に呼び出し元に制御権を返すコードブロックです.
•CおよびC++プログラミングでは、関数に実行可能なすべてのコードが存在します.
•関数は、通常、プログラムの実行中に複数の場所で複数回実行(呼び出し)されます.
•サブルーチンを終了すると、プログラムは呼び出し後にポイントに分岐(戻る)します.
•パラメータを使用して、関数の演算を変更できます.
•関数宣言の引数は、関数呼び出しによって渡される引数に明確に対応しています.
•関数に戻りタイプがある場合は、呼び出しを戻り値として計算し、変数として保存できます.
#include <iostream>
using namespace std;

float calculateCircle(int radius) {
	return 3.14 * radius * radius;
}

int main() {
	int min, max, radius;
	cout << "Enter Min (1~10) : " ;
	cin >> min;
	cout << "Enter Max (Min~10) : " ;
	cin >> max;

	for (int i = min; i < max + 1; i++) {
		cout << "Radius " << i << "=3.14x" << i << "x" << i << "=" << calculateCircle(i) << "\n";
	}

		
}
結果:
Enter Min (1~10) : 2
Enter Max (Min~10) : 10
Radius 2=3.14x2x2=12.56
Radius 3=3.14x3x3=28.26
Radius 4=3.14x4x4=50.24
Radius 5=3.14x5x5=78.5
Radius 6=3.14x6x6=113.04
Radius 7=3.14x7x7=153.86
Radius 8=3.14x8x8=200.96
Radius 9=3.14x9x9=254.34
Radius 10=3.14x10x10=314

Inline Function


•インラインキーを使用してインライン関数を定義すると、コンパイラは関数を呼び出すたびに関数呼び出しを関数の実際のコードに置き換えます.
•関数-呼び出し-オーバーヘッドが格納されているが、メモリパネルが生成されるため、ローの関数の実行速度は通常の関数よりやや速い.
-10行の関数を呼び出すと、10個の関数のコピーがコードに挿入されます.
•インライン関数は、頻繁に呼び出される小さな関数に適しています.
変数として単独で宣言せず、関数の戻り値を直接使用できます.
#include <iostream>

using namespace std;

inline int inc(int x) {
	return x + 1;
}
int main() {
	cout << inc(1) << endl;
}

Recursive Functions再帰関数


再帰関数は、自己または関数呼び出しを呼び出す潜在的な周期で呼び出される関数です.

factorial

#include <iostream>

using namespace std;

int Factorial(int n) {
	if (n == 1)
		return 1;
	return Factorial(n - 1) * n;
}

int main() {
	int result = Factorial(4);
	cout << "Factorial :" << result << "\n";

	return 0;
}

fibonacci

#include <iostream>

using namespace std;

int Fibo(int n) {
	if (n == 1)
		return 1;
	if (n == 2)
		return 1;
	return Fibo(n - 1) + Fibo(n-2);
}

int main() {
	int result = Fibo(8);
	cout << "Fibo :" << result << "\n";

	return 0;
}

🔑カテゴリ


•クラスは、データと関数(メソッドとも呼ばれる)をメンバーとするキーワードクラスを使用して宣言されるカスタムタイプまたはデータ構造です.
•クラスは、データ構造の拡張概念です.データ構造のようにデータ・メンバーを含めることもできますが、メンバーとしての機能を含めることもできます.

インスタンス(オブジェクト)


•インスタンスは、クラスの具体的な宣言です.
•正式な「instance」は「object」と同義である.
•各インスタンスには独自のデータがあります.
•作成したインスタンスをインスタンス化と呼びます.

アクセス指定子(private、public、protected)


指定されたアクセス性privateAccess only in this class(not from out the class)の個別private:デフォルトでは、クラスの変数はprivate、publicAccess in the class、from out the classとして格納されているようです.protectedThe members declared as "protected"cannot be accessed from outside the class, but can be accessed from a derived class. This is used when inheritance is applied to the members of a class. クラス外部からアクセスできませんが、派生クラスからアクセスできます.このオプションは、継承がクラスメンバーに適用される場合に使用されます.

宣言と定義


クラスの場合、クラス内で宣言し、クラス外でメソッドを定義できます.
ex)クラス外で計算領域メソッドを定義します.
#include <iostream>
using namespace std;

class Quadrangle {
private:
	int width;
	int height;
	int area;

public:
	int CalculateArea(int argWidth, int argHeight);
	void SetWidth(int width){
		Quadrangle::width = width;
	}
	void SetHeight(int height) {
		Quadrangle::height = height;
	}

};

int Quadrangle::CalculateArea(int argWidth, int argHeight) {
	width = argWidth;
	height = argHeight;
	area = width * height;
	return area;
}

void main() {
	int w, h;
	Quadrangle cQ;

	cout << "Enter Width : ";
	cin >> w;
	cout << "Enter Height : ";
	cin >> h;

	cQ.SetHeight(h);
	cQ.SetWidth(w);
	cout << "Area (w = " << w << ", h=" << h << ") =" << cQ.CalculateArea(h, w);

}

クラス宣言テスト


#include <iostream>
#define _CRT_SECURE_NO_WARNINGS
using namespace std;

class Circle {
private:
	int radius;

public:
	void SetRadius(int radius_) {
		radius = radius_;
	}

	float CalculateArea() {
		return radius * radius * 3.14;
	}
};



int main() {
	int radius = 0;
	Circle circle;

	printf("Input radius: (cm)\n");
	scanf_s("%d", &radius);

	circle.SetRadius(radius);
	printf("Area (radius=%d) = %0.3f\n", radius, circle.CalculateArea());
}
結果:
Input radius: (cm)
3
Area (radius=3) = 28.260

作成者と消滅者


生成者
•クラスインスタンスを作成するたびにコンストラクション関数が呼び出されます.
•ジェネレータの名前はクラスと同じで、フォーマットは返されません.
•クラスにコンストラクション関数がない場合でも、コンパイラはデフォルトデフォルトデフォルトデフォルトデフォルトデフォルトデフォルトデフォルトデフォルトデフォルトと呼ばれるコンストラクション関数生成コードを生成します.
消滅者
•クラス内のオブジェクトが破棄されるたびに、消滅者が呼び出されます.
•消滅者の名称は同じように定義されていますが、前に「~」があります.
•クラスに消滅者がいなくても、コンパイラはエラー消滅者と呼ばれる消滅者生成コードと呼びます.
#include <iostream>
#define _CRT_SECURE_NO_WARNINGS
using namespace std;

class Unit {
	int status;
public:
	Unit(int a);
	~Unit();
	void fly();
};

Unit::Unit(int a) : status(a) {};
Unit::~Unit() {
	cout << "Unit Destructing";
	status = 0;
}

void Unit::fly() {
	cout << status << endl;
}

int main() {
	Unit oUnit(1);
	oUnit.fly();
	return 0;
}
上記の作成者または消滅者定義では`
Unit::Unit(int a) {
	status = a;
}
消滅者定義
 Unit::Unit(int a) : status(a) {};
置換可能

生成者消滅者テスト


#include <iostream>

using namespace std;

class Student {
	int Year;
	int ID;
	int Grade;

public:
	Student(int Year, int iD, int grade) : Year(Year), ID(iD), Grade(grade) {}
	void showData() {
		cout << "Year : " << Year << ", ID: " << ID << ", Grade : " << Grade;
	}
};

int main() {
	Student s(2017, 100100, 1);
	s.showData();
}
結果:Year:2017,ID:100000,Grade:1

継承


•継承により、他のクラスの観点からクラスを定義でき、アプリケーションの作成とメンテナンスを簡素化できます.
•コードの再利用と元のソフトウェア拡張から独立したメカニズムを可能にします.
#include <iostream>
using namespace std;

class NPC {
	int defense;

public:
	void SetDefense(int n);
	int GetDefense();
};

class Grunt : public NPC {
	int armor;

public:
	void SetArmor(int n);
	int GetArmoredDefense();
};

void NPC::SetDefense(int n) {
	defense = n;
}

int NPC::GetDefense() {
	return defense;
}

void Grunt::SetArmor(int n) {

	armor = n;
}

int Grunt::GetArmoredDefense() {
	return armor + GetDefense();
}

int main() {
	Grunt oUnit;
	oUnit.SetDefense(10);
	oUnit.SetArmor(20);

	cout << "Get Armored Defense : " << oUnit.GetArmoredDefense() << "\n";
	return 0;
}

GruntクラスからNPCクラスの共通要素を取得し、それらを使用してメソッドによって防御値を提供することができます.

継承テスト


#include <iostream>

using namespace std;
class P {
public:
	int x=10;
protected:
	int y=10;
private:
	int z=10;
};

class A : public P {

};

class B : protected P{

};

class C : private P{

};

int main() {
	A a;
	B b;
	C c;
	cout << a.x << endl;
	cout << a.y << endl;
	cout << a.z << endl;
	cout << b.x << endl;
	cout << b.y << endl;
	cout << b.z << endl;
	cout << c.x << endl;
	cout << c.y << endl;
	cout << c.z << endl;
	
}
結果:
a.x出力を除くと、すべての出力にエラーが発生します
n/a.理由
Pがpublicに継承されたa受信アクセス制限者がpublic異常のxをpublic変数とし,残りのアクセス制限者が受信する
b保護されたxのアクセス制限は保護されたxより大きいため、すべての変数は共通ではないため、アクセスできない
cもprivateより広い範囲の要素をすべてprivateに変換して継承する

複数の継承


クラスは、複数の親から変数とメソッドを継承できます.クラスは、特定のクラスから継承できる単一の継承とは異なります.

複数の継承テスト



#include <iostream>
//re: 실수
//im: 허수

using namespace std;

class Plus {
public:
	void printPlus(int re1, int im1, int re2, int im2) {
		cout << "Plus: " << re1 + re2 << "+" << im1 + im2 << "j" << endl;
	};
};

class Minus {
public:
	void printMinus(int re1, int im1, int re2, int im2) {
		cout << "Minus: " << -re1 + re2 << "+" << -im1 + im2 << "j" << endl;
	};
};

class Complex : public Plus, public Minus {
private:
	int re;
	int im;

public:
	Complex() : re(0), im(0) {};

	void setCom(int are, int aim) {
		re = 0;
		im = 0;
		re += are;
		im += aim;
	}

	void plus(int are, int aim) {
		printPlus(are, aim, re, im);
	}

	void minus(int are, int aim) {
		printMinus(are, aim, re, im);
	}
};
void main() {
	Complex a;

	a.plus(2, 3);
	a.minus(2, 3);

	a.setCom(1, 1);
	a.plus(2, 3);
	a.minus(2, 3);
}

クラスポインタ


•クラスのポインタは、構造体のポインタとまったく同じ動作をします.
•メンバー・アクセス演算子「->」が使用可能
ex)
Grunt *pUnit = new Grunt;

pUnit -> SetDefence(10);
pUnit -> SetArmor(20);

delete pUnit;
or
Grunt oUnit;
Grunt *pUnit;
pUnit = &oUnit;
pUnit->SetDefense(10);
pUnit->SetArmor(20);

クラスポインタテスト


void main() {
	Complex *a = new Complex;

	a->plus(2, 3);
	a->minus(2, 3);

	a->setCom(1, 1);
	a->plus(2, 3);
	a->minus(2, 3);
	
	delete a;
}

継承ジェネレータ


•作成者を継承しません.
•親クラスの作成者は、子作成者によって暗黙的または明示的に呼び出される必要があります.
•親クラスの作成者を最初に呼び出し、次に子クラスの作成者を呼び出します.
継承されたサブクラスを呼び出す場合は、まず親クラスの作成者を呼び出し、次に自分の作成者を呼び出します.
Derived::Derived(int a):Base(a)ジェネレータを明示的に呼び出し、親パラメータを持つジェネレータを呼び出します.
#include <iostream>
using namespace std;

class Base {
public:
	Base();
	Base(int a);
	~Base();
};

Base::Base() {
	cout << " Constructor of Base " << endl;
} 

Base::Base(int a) {
	cout << "Constructor of Base " << a << endl;
}

Base::~Base() {
	cout << " Destructor of Base " << endl;
} 

class Derived : public Base {
public: 
	Derived();
	Derived(int a);
	~Derived();
};

Derived::Derived() {
	cout << " Constructor of Derived " << endl;
}

Derived::Derived(int a){
	cout << " Constructor of Derived " << a << endl;
}

Derived::~Derived() {
	cout << " Destructor of Derived " << endl;
}

void main() {
	Derived obj1;
	Derived obj2(1);
}

ジェネレータ継承テスト


#include <iostream>
using namespace std;

class Student {
public:
	Student() : grade(0) {}
	Student(int argGrade) : grade(argGrade) {}
	~Student(){}
	int GetGrade() { return grade; }

private:
	int grade;
};

class Calculator {
public:
	Calculator() : numberOfStudent(0) {}
	void AddStudent(Student argStudent);
	int Sum();

private:
	Student student[50];

protected:
	int numberOfStudent;
};

void Calculator::AddStudent(Student argStudent) {
	//student 객체 추가하기
	student[numberOfStudent++] = argStudent;
}

int Calculator::Sum() {
	int sum = 0;
	for (int i = 0; i < numberOfStudent; i++)
		sum +=student[i].GetGrade();
	return sum;
}

class CalculatorEx :public Calculator {
public:
	int Average() {
		float average(0.0f);
		average = Sum() / float(numberOfStudent);
		return average;
	}
};

int main() {
	Student student1(30);
	Student student2(90);
	Student student3(100);
	Student student4(50);

	CalculatorEx cal;
	cal.AddStudent(student1);
	cal.AddStudent(student2);
	cal.AddStudent(student3);
	cal.AddStudent(student4);
	
	cout << "Sum of grades : " << cal.Sum() << endl;
	cout << "Average of grades : " << cal.Average() << endl;

}