C++大一基础知识

目录

一、程序控制

①输入输出

Ⅰ.cin&cout

Ⅱ.scanf&printf

②运算与符号

Ⅰ常用数学函数#include

Ⅱ.数据类型转换

③控制结构

④函数

Ⅰ.函数定义

Ⅱ函数使用

二、数据结构

①一维数组

排序与查找

②多维数组

③指针

Ⅰ字符,指针运算

Ⅱ字符串函数#include

Ⅲ指针参数与动态内存

④结构:struct

⑤链表

三、文件操作

Ⅰ基本文件输入输出

Ⅱ文件指针

四、类和对象

①类的创建和使用

②静态成员

③构造函数

④类的复合

⑤This指针

⑥友元

Ⅰ友元函数

Ⅱ友元类

五、运算符重载

①原理

②方式

Ⅰ成员函数重载

Ⅱ友元函数重载

③单目与双目运算符重载

Ⅰ单目(目表示操作数)

Ⅱ流插入和流提取运算符的重载

Ⅲ双目

Ⅳ类型转化

六、继承派生多态


一、程序控制

①输入输出

Ⅰ.cin&cout

流操作算子 #include

setbase(n),进制,n=8,10,16
setprecision(n),浮点数精度设置为n
setw(n),域宽n,小于n空位填充,大于n输出所有
setiosflags(long),long,流格式状态标志

#include 
#include
#include
using namespace std;
int main()
{
	//setbase(n),进制,n=8,10,16
	int a = 1000;
	cout << "oct(八进制):"<

其他流输入输出

cin.get(char) 抽取下一个字符
cin.peek() 读取下一个字符
cin.putbact(char) 将字符写入输入流的开头
cin.ingnore(int, char) 忽略前面int个或char及其之前的字符
cin.getline(char*, int, char) 最多读取前面n个字符或读取到char截止

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
using namespace std;
int main()
{
	string line;

	//getline(cin,str)
	//cin.get(char) 抽取一个字符
	char gch;
	cin.get(gch);
	getline(cin, line);//getline抽取整行的输入流
	cout << "cin.get()抽取的字符是:" << gch<

Ⅱ.scanf&printf

格式化输入输出#include

printf(<格式化控制>,<参数列表>)
scanf(<宽度>,<转换说明符>)

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
using namespace std;
int main()
{
	//printf(<格式化控制>,<参数列表>)
	//<标志>:-左对齐,+显示符号,0用0填充域宽
	//<域宽>:小于域宽空白填充,大于按照实际输出
	//<精度>:整数:至少输出的数字个数,少的0补前面,字符串:输出最大长度
	//<转换说明符>:数据转换类型
	double num =-123.456;
	printf("%+015.5f\n", num);//0:缺项补0,15:域宽,5:精度

	//scanf(<宽度>,<转换说明符>)
	char c;
	int d;
	scanf("%3c%3d",&c,&d);
	cout << "c: " << c << endl<<"d: "<

②运算与符号

Ⅰ常用数学函数#include

abs
ceil 向上取整
exp(x) e^x
floor 向下取整
pow(x,y) x^y
log 以e为底数
log10 以10为底数

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include

using namespace std;
int main()
{
	cout <<"abs(-1)="<< abs(-1) << endl;
	cout << "ceil(0.5)="<Ⅱ.数据类型转换 
  

隐式转换
显式转换
ASCII码与BOOL
运算符
三目运算符:<1> ? <2> : <3>

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
using namespace std;
int main()
{
	//隐式转换
	int e = 3;
	double f = e + 3.12;

	//显式转换
	cout << "double(3/2)="<③控制结构 
  

两个数的值交换
三个数的排序
switch - case-break - defalut

方便跳出多重循环

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
using namespace std;
int main()
{
	//两个数的值交换
	int e = 1, f = 2;
	int t = e;
	e = f;
	f = t;

	//三个数的排序
	int a = 1, b = 2, c = 3;
	int maxab = a > b ? a : b;
	int minab = a + b - maxab;
	int max = maxab > c ? maxab : c;
	int temp = (maxab + c) - max;
	int min = temp > minab ? minab : temp;
	cout << "max:" << max << "\n" << "mid:" << (a + b + c) - max - min << endl<<"min:"<> command;
		switch (command)
		{
			case 1:
				cout << "1号任务" << endl;
				break;//不能缺少break语句
			case 2:
				cout << "2号任务" << endl;
				break;
			case 0:
				flag = 0;
				break;
			default:
				cout << "你干嘛" << endl;
		}
	}

    //goto 方便跳出多重循环
	for (int i = 1; i < 10; i++)
	{
		for (int j = 1; j < 10; j++)
		{
			for (int k = 1; k < 10; k++)
			{
				if (3*i + 4 * j + 5 * k == 100)
				{
					printf("i=%d,j=%d,k=%d是3*i+4*j+5*k=100的解\n", i, j, k);
					goto flag1;
				}
			}
		}
	}
	flag1:
		cout<<"flag1";
	return 0;
}
out:

max:3
mid:2
min:1
1
1号任务
4
你干嘛
0
i=8,j=9,k=8是3*i+4*j+5*k=100的解
flag1

④函数

Ⅰ.函数定义

函数头放前面,具体定义放后面,增强可读性

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
using namespace std;

//<返回类型><函数名字>(<参数列表>){<语句>}
bool isprime(int n);//函数头放前面,具体定义放后面,增强可读性
void goldbach(int n);

int main()
{
	cout << "15~30的偶数哥德巴赫猜想验证\n";
	for (int i = 16; i <= 30; i+=2)
	{
		goldbach(i);
		cout << endl;
	}
	return 0;
}

// function library
bool isprime(int n) //判断是否为素数
{
	int c = 1;
	for (int i = 2; i <= n; i++)
	{
		if (n % i == 0)
		{
			c++;
		}
	}
	return c == 2 ? true : false;
}
void goldbach(int n)
{
	for (int i = 2; i < n / 2 + 1; i++)
	{
		if (isprime(i) && isprime(n - i))
		{
			printf("%d=%d+%d", n, i, n - i);
			break;
		}
	}
}
out:

15~30哥德巴赫猜想验证
16 = 3 + 13
18 = 5 + 13
20 = 3 + 17
22 = 3 + 19
24 = 5 + 19
26 = 3 + 23
28 = 5 + 23
30 = 7 + 23

Ⅱ函数使用

传值
传引用
函数重载,函数名字可相同,但传参类型个数或顺序不同
作用域:块作用域,{}, 全局作用
存储类别:auto, static.(auto现在已经被淘汰了, 函数内直接定义即可)

递归函数:汉诺塔问题

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
using namespace std;

int a = 1;
double max(double x, double y);
void swap(double& x, double& y);
int max(int x, int y);
void storeauto(int &x, int &y);
void storesta(int& x, int& y);
void hannuo(int n, char s, char m, char t);//n:规模,s:源柱,m:辅柱,t:目标柱

int main()
{
	//传值
	double x = 1.1, y = 2.2;

	//传引用
	printf("x=%.1f,y=%.1f\t", x, y); 
	swap(x, y);//这里不用写(&x,&y)
	printf("after swapping \tx=%.1f,y=%.1f\n", x, y);
	
	//函数重载,函数名字可相同,但传参类型个数或顺序不同
	int r = 1, s = 2;
	cout << max(r, s)<" << t << endl;
	}
	else
	{
		hannuo(n - 1, s, t, m);//n-1个盘子移到辅柱
		cout << s << "->" << t << endl;//最后一个移到目标柱
		hannuo(n - 1, m, s, t);//辅柱变为源柱
	}
}
out:

x=1.1,y=2.2     after swapping  x=2.2,y=1.1
2
块1:a=1
块2:a=2
全局:a=1
q=2,w=4
storeauto(q,w)调用1次后,q=3,w=5
storeauto(q,w)调用2次后,q=4,w=6

q=4,w=6
storesta(q,w)调用1次后,q=5,w=7
storesta(q,w)调用2次后,q=7,w=9
A->B
A->C
B->C
A->B
C->A
C->B
A->B

二、数据结构

①一维数组

排序与查找

一维数组 a[n], n是数据个数
排序 交换(每次找到都交换),选择(先找最值再交换),快排
内置函数#include
查找:二分查找

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
#include
#include
using namespace std;

void quick_sort(int a[], int start, int end);//快排自定义
int binary_search(vector& nums, int target);

int main()
{
	//一维数组 a[n],n是数据个数
	int d[4]; //大小是常量值
	int b[] = { 1,2,3,4 };//根据数目确定大小
	float c[5] = { 1.2 };//缺省值0
	
	//排序 交换(每次找到都交换),选择(先找最值再交换),快排
	//交换排序
	int a[10] = { 1,2,3,5,6,8,10,9,7,4 };
	for (int i = 0; i < 10 - 1; i++)
	{
		for (int j = i+1; j < 10; j++)
		{
			if (a[i] > a[j]) 
			{
				int temp = a[i];
				a[i] = a[j];
				a[j] = temp;
			}
		}
	}
	cout << "交换排序结果:";
	for (int i = 0; i < 10; i++) 
	{
		cout << a[i] << " ";
	}
	cout << endl;
	//选择排序
	for (int i = 0; i < 10 - 1; i++)
	{
		int min = i;
		for (int j = i + 1; j < 10; j++)
		{
			if (a[j] < a[i])
			{
				min = j;
			}
		}
		if (i != min)
		{
			int temp = a[i];
			a[i] = a[min];
			a[min] = a[i];
		}
	}
	cout << "选择排序结果:";
	for (int i = 0; i < 10; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;
	//快排
	quick_sort(a, 0, 10- 1);
	cout << "快排结果:";
	for (int i = 0; i < 10; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;
	//内置函数#include
	sort(a, a + 10, greater());//左闭右开,greater,降序,int 类型,默认为升序

	//查找:二分查找
	vector nums = { 1, 3, 5, 7, 9, 11, 13, 15, 17 };
	int target = 11;

	int index = binary_search(nums, target);
	if (index == -1) {
		cout << "Target not found" << endl;
	}
	else {
		cout << "Target found at index " << index << endl;
	}

	return 0;
}

// function library
void quick_sort(int a[], int start, int end)
{
	if (start >= end) {
		return;
	}

	int pivot = a[start];
	int left = start + 1, right = end;

	while (left <= right) {
		if (a[left] < pivot && a[right] > pivot) {
			swap(a[left], a[right]);
			left++;
			right--;
		}
		if (a[left] >= pivot) {
			left++;
		}
		if (a[right] <= pivot) {
			right--;
		}
	}

	swap(a[start], a[right]);
	quick_sort(a, start, right - 1);
	quick_sort(a, right + 1, end);
}
int binary_search(vector& nums, int target) 
{
	int left = 0, right = nums.size() - 1;

	while (left <= right) {
		int mid = left + (right - left) / 2;
		if (nums[mid] == target) {
			return mid;
		}
		else if (nums[mid] < target) {
			left = mid + 1;
		}
		else {
			right = mid - 1;
		}
	}

	return -1;
}
out:

交换排序结果:1 2 3 4 5 6 7 8 9 10
选择排序结果:1 2 3 4 5 6 7 8 9 10
快排结果:10 9 8 7 6 5 4 3 2 1
Target found at index 5

②多维数组

初始化 a[m][n], m行n列,按行连续储存
作为函数参数, 指定数组的每一维的大小

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
#include
#include
using namespace std;

int sum(int arr[][3], int rows, int cols);

int main()
{
	//多维数组 初始化 a[m][n],m行n列,按行连续储存
	int a[2][2] = { {2},{2,3} };//缺省值为0
	int b[2][2] = { 1,2,3};//按行读入
	int c[][2] = { {1,2},{1} };//只能省略第一维

	//多维数组 作为函数参数
	//由于多维数组的内存布局是连续的,因此在将多维数组作为形参传递时,必须指定数组的每一维的大小
	int arr[2][3] = { {1, 2, 3}, {4, 5, 6} };
	int s = sum(arr, 2, 3);
	cout << "The sum of the array is: " << s << endl;

	return 0;
}

// function library
int sum(int arr[][3], int rows, int cols)
{
	int s = 0;
	for (int i = 0; i < rows; ++i) {
		for (int j = 0; j < cols; ++j) {
			s += arr[i][j];
		}
	}
	return s;
}
out:

The sum of the array is : 21

③指针

Ⅰ字符,指针运算

加密问题
二维字符数组
指针运算:& 地址运算* 复引用 + -算术运算 前移后移,计算距离,关系运算,赋值
指针操作数组
指针数组:数组存放指针

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
#include
#include
using namespace std;

int main()
{
	//加密问题
	char a[10];
	cin >> a;
	int l = 0;
	while (a[l] != '\0')
	{
		a[l] = a[l] + 'A' - 'a'+3;
		l++;
	}
	cout << "输入字符串长度为:" << l << "\t加密后为:" << a << endl;

	//二维字符数组
	char s[2][10];
	cin >> s[0] >> s[1];
	cout << s[0] << endl << s[1] << endl;

	//指针运算:&地址运算 *复引用 +-算术运算 前移后移,计算距离,关系运算,赋值
	//& 地址运算
	int* yptr;
	int y = 5;
	yptr = &y;//得到指向y的指针
	//*复引用
	int* p1, * p2;//同时定义两个指针都要打*
	int y1 = 2, y2 = 3;
	p1 = &y1;
	p2 = &y2;
	*p1 += 1;
	printf("y1=%d,y2=%d\n*p1=%d,*p2=%d\n", y1, y2, *p1, *p2);
	//+-算术运算 前移后移,计算距离
	cout << "p1-p2=" << p1 - p2 << endl;
	//关系运算
	cout << "p1Ⅱ字符串函数#include 
  

int strlen(const char*) 计算字符串长度
char* strcpy(char* dest, const char* src) 将src指向的空间复制到dest
char* strcat(char* dest, const char* src) 将src指向的空间连接到dest之后
int strcmp(const char* s1, const char* s2)    逐一比较字典序,s1 < s2返回1
char* strchr(const char* s, int c) 在s中查找第一个对应ASCII码为c的字符并返回位置,否则返回NULL
综合应用 : countstring(const chat* s1, const char* s2),查找子串s2在s1中的出现次数

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
#include
#include
using namespace std;

int countstring(const char* s1, const char* s2);

int main()
{
	//int strlen(const char*) 计算字符串长度
	const char* c1 = "hello world";
	char c2[] = "hello world"; //两种初始化方式
	cout << "strlen(c1)=" << strlen(c1) << "\tstrlen(c2)=" << strlen(c2) << endl;

	//char* strcpy(char* dest,const char* src) 将src指向的空间复制到dest
	char a[20]="hello", b[20] = "world";
	strcpy(a, b);//a原来有的内容不会保留
	cout << "strcpy(a, b),a=" << a << endl;

	//char* strcat(char* dest,const char* src) 将src指向的空间连接到dest之后
	strcat(a, b);//拼接在一起
	cout << "strcat(a, b),a=" << a << endl;

	//int strcmp(const char* s1,const char* s2)	逐一比较字典序,s1

Ⅲ指针参数与动态内存

const与指针
动态分布:new& delete, malloc& free

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
#include
#include
using namespace std;

int main()
{
	//const与指针
	const int* p1; // 指向常量的非常量指针
	int a = 1;
	p1 = &a; // OK,p1指向a,但不能通过p1修改a的值
	int b = 2;
	p1 = &b; // OK,p1指向b,但不能通过p1修改b的值
	int* const p2 = &a; // 指向非常量的常量指针
	*p2 = 3; // OK,可以通过p2修改a的值
	int c = 4;
	// p2 = &c; // ERROR,p2是常量指针,不能改变指向的对象
	const int* const p3 = &b; // 指向常量的常量指针
	// *p3 = 5; // ERROR,不能通过p3修改b的值
	int d = 6;
	// p3 = &d; // ERROR,p3是常量指针,不能改变指向的对象
	
	//动态分布:new&delete,malloc&free
	int x; //数组的长度
	cin >> x;//运行时才能确定x的值
	float* scores = new float[x];
	cout <<"分配的内存空间长度:"<< sizeof(float) * x << endl;
	delete[]scores;//及时释放,防止内存泄露,建议每次new就直接写delete

	int* s = (int*)malloc(sizeof(int) * 4);
	for (int i = 0; i < 4; i++)
	{
		cin >> s[i];
	}
	for (int i = 0; i < 4; i++)
	{
		cout << s[i] << " ";
	}
	free(s);

	return 0;
}

// function library
out:

5
分配的内存空间长度:20
1
2
3
4
1 2 3 4

④结构:struct

定义与声明
初始化
结构与函数

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
#include
#include
using namespace std;

//定义与声明
struct birthday
{
	int year;
	int month;
	int day;
};
struct lifting
{
	char name[20];
	float weight;
	birthday date;//可以包含其他strcut
	lifting* a;//可以是指向本结构类型的指针
}lift1,lift2;//声明两个变量
void print(lifting* l);

int main()
{
	//初始化
	lift1 = { "张三",57,{2005,1,13},&lift2 };//lift1.a指向lift2
	lifting* p1 = &lift1;
	//p1->name = "张三";这里不能直接修改
	strcpy(p1->name, "李四"); // 使用strcpy函数修改name的值
	cout << lift1.name;
	cout << "生日为:" << lift1.date.year<<" "<< lift1.date.month<<" "<< lift1.date.day<name << endl <<"体重:"<< l->weight<

⑤链表

node* insertTail(node* h, node* t) //尾部插入
node* insertHead(node* h, node* t)//头部插入
node* insertSort(node* h, node* t) //从小到大插入
node* search(node* h, int num) //查找指定节点
node* delAt(node* h, int i)//删除指定位置节点
node* delHas(node* h, int n) //删除含有指定元素的节点
int listLength(node* h)//计算链表长度

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
#include
#include
#include
using namespace std;

struct node 
{
	int data;
	node* next;
};
node* insertTail(node* h, node* t) //尾部插入
{
    if (h == nullptr) 
    {
        return t;// 如果当前链表为空,直接将待插入结点作为链表头并返回
    }
    node* p = h;
    while (p->next != nullptr) {
        p = p->next; // 找到链表的最后一个结点
    }
    p->next = t;// 将链表的最后一个结点的next指针指向待插入结点
    return h;
}
node* insertHead(node* h, node* t)//头部插入
{
    if (h == nullptr)
    {
        return t;
    }
    t->next = h;
    return t;
}
node* insertSort(node* h, node* t) //从小到大插入
{
    if (h == NULL) 
    { 
        t->next = NULL;// 空链表,直接将结点t插入
        return t;
    }
    if (t->data <= h->data) 
    { 
        t->next = h;// 将结点t插入链表头
        return t;
    }
    node* p = h;
    while (p->next != NULL && p->next->data < t->data) {
        p = p->next;
    }
    t->next = p->next;
    p->next = t;
    return h;
}
node* search(node* h, int num) //查找指定节点
{
    if (h == NULL)// 空链表
    { 
        return NULL;
    }
    node* p = h;
    while (p != NULL) {
        if (p->data == num) {
            return p;
        }
        p = p->next;
    }
    return NULL; // 循环结束,未找到该结点
}
node* delAt(node* h, int i)//删除指定位置节点
{
    int num = 0;
    node* p = h;
    while (p->next != nullptr)
    {
        num++;
        p = p->next;
    }
    if (i == 0)
    {
        return h->next;
    }
    else if (i > num)
    {
        return h;
    }
    else
    {
        node* t = h;
        node* m = h;
        for (int j = 0; j < i; j++)
        {
            t = m;
            m = t->next;
        }
        t->next = m->next;
        return h;
    }
}
node* delHas(node* h, int n) //删除含有指定元素的节点
{
    if (h == NULL)  // 空链表
    {
        return h;
    }
    if (h->data == n) 
    { 
        node* p = h;
        h = h->next;// 删除头结点
        free(p);//释放原来头节点的内存
        return h;
    }
    node* p = h;
    while (p->next != NULL && p->next->data != n) 
    { 
        p = p->next;// 找到要删除结点的前驱结点
    }
    if (p->next == NULL) 
    { 
        return h;// 要删除的结点不存在
    }
    node* q = p->next; // 被删除结点
    p->next = q->next; // 将被删除结点从链表中删除
    free(q);//释放内存

    return h;
}
int listLength(node* h)//计算链表长度
{
    int c = 0;
    while (h != nullptr)
    {
        c++;
        h = h->next;
    }
    return c;
}

三、文件操作

Ⅰ基本文件输入输出

打开文件 ios::in打开供读取,out打开供写入, app打开写入末尾
输入输出
example:文本操作与二进制操作

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
using namespace std;

struct person
{
	char name[16];
	int number;
}me={"zhangsan",20220001},t,r;
int main()
{
	/*
	//打开文件 ios:: in打开供读取,out打开供写入,app打开写入末尾
	ofstream ofs;
	ofs.open("f1.txt", ios::out);
	//或者:ofstream ofs("f1.txt",ios::out)
	//关闭
	ofs.close();

	//输入输出
	ifstream ifs("f1.txt", ios::in);
	int n;
	ifs >> n;
	ifs.close();
	ofstream ofs("f1.txt", ios::out);
	int n = 123;
	ofs << n; ofs.close();

	//块输入输出 ifstram&read,ofstream&write
	ifstream ifs("f1.txt", ios::in);
	int n;
	ifs.read((char*)&n, sizeof(int));
	ifs.close();
	ofstream ofs("f1.txt", ios::out);
	int n = 123;
	ofs.write((char*)&n, sizeof(n)); ofs.close();
	*/

	//example
	//文本操作
	ofstream f("a.txt", ios::out);
	f << me.name << " " << me.number << endl;
	f.close();
	ifstream f1("a.txt", ios::in);
	f1 >> t.name >> t.number;
	f1.close();
	cout << t.name << " " << t.number << endl;
	//二进制操作
	ofstream g("b.txt", ios::out|ios::binary);
	g.write((char*)&me, sizeof(me));
	g.close();
	ifstream g1("b.txt", ios::in |ios::binary);
	g1.read((char*)&r, sizeof(r));
	g1.close();
	cout << r.name << " " << r.number << endl;



	return 0;
}

// function library
out:
zhangsan 20220001
zhangsan 20220001

Ⅱ文件指针

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
using namespace std;

struct date
{
	int year, month, day;
};

int main()
{
	//seekg(streamoff off,ios::seek_dir dir) 读文件时修改FP
	//seekp(streamoff off,ios::seek_dir dir) 写文件时修改FP
	//off:偏移量,单位字节 dir:位置常量,ios:: beg起始,cur当前,end结尾

	//example
	int i,n;
	cin >> n;
	date* t=new date[n]; //动态分配内存
	for (i = 0; i 

四、类和对象

①类的创建和使用

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;

//类和对象
class complex
{
public:
    complex(double r = 0, double i = 0)
    {
        real = r;
        imag = i;
    }
    ~complex() {};//析构函数,撤销对象时自动调用
    complex mul(complex x)
    {
        double r = real * x.real - imag * x.imag;
        double i = real * x.imag + imag * x.real;
        return complex(r, i);
    }
    complex add(complex x)
    {
        return complex(real + x.real, imag + x.imag);
    }

    void output()
    {
        if (imag >= 0)
        {
            cout << "(" << real << "+" << imag << "i)" << endl;
        }
        else
        {
            cout << "(" << real << imag << "i)" << endl;
        }
    }
private:
    double real, imag;
};

int main()
{
    complex a(1.2, 2.3), b(5, -6.7), c, d;
    c = a.add(b); d = a.mul(b);
    c.output();
    d.output();
    return 0;
}
out:
(6.2 - 4.4i)
(21.41 + 3.46i)

②静态成员

静态成员的声明:static
访问静态成员:对象名 / 对象引用 + 点操作符号,classname + ::,类指针 + 箭头
作用域与析构函数

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;

//静态成员的声明:static
class book
{
public:
    book(const char* bookname);
    ~book();//析构函数
    static int getbooknum();//静态成员函数只能访问静态成员
private:
    char name[50];//书名
    static int booknum;//静态数据,不依赖对象而存在
};

//访问静态成员:对象名/对象引用+点操作符号,classname+::,类指针+箭头
book::book(const char* bookname)
{
    strcpy(this->name, bookname);//类指针+箭头
    booknum++;//对象产生,booknum增加
}
book::~book()
{
    booknum--;//对象撤销时,booknum减少
}
int book::booknum = 0;//初始化类的静态成员
int book::getbooknum()
{
    return booknum;
}
int main()
{
    cout << "Thers is " << book::getbooknum() << " book." << endl;
    {//块1
        book one("C++程序设计");//创建一个对象
        cout << "After book one created,there is " << one.getbooknum() << " book." << endl;//对象名+.
        {//块2
            book two("Python程序设计");
            cout << "After book two created,there are " << two.getbooknum() << " books." << endl;
        }//块2结束,自动撤销two(作用域)
        cout << "After book two destroyed,there is " << one.getbooknum() << " book." << endl;
    }//块1结束,自动撤销one
    cout << "After book one destroyed,there is " << book::getbooknum() << " book." << endl;
    return 0;
}

out:

Thers is 0 book.
After book one created,there is 1 book.
After book two created,there are 2 books.
After book two destroyed,there is 1 book.
After book one destroyed,there is 0 book.

③构造函数

带默认参数的构造函数
复制构造函数(创建信息相同的对象)

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;

class circle
{
public:
    //带默认参数的构造函数
    circle(double a = 5.0, double b = 5.0, double c = 5.0)//每个参数的类型都要写清楚
    {
        x = a;
        y = b;
        c > 0 ? r = c : r = 5.0;//三目运算符
    }
    //复制构造函数(创建信息相同的对象)
    circle(circle& c)
    {
        x = c.x; y = c.y; r = c.r;
    }
    ~circle() {};
    void print(circle &c);
private:
    double x, y, r;
};
void circle::print(circle& c)
{
    cout << "x=" << c.x << "\ty=" << c.y << "\tr=" << c.r<

④类的复合

成员对象在包含它的对象之前被建立
成员函数的构造函数被大对象的构造函数调用
大对象的成员函数对成员对象来说依然是外部函数,需要遵循访问规则,注意调用格式

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;
#define pi 3.14
class circle
{
public:
    //带默认参数的构造函数
    circle(double a = 5.0, double b = 5.0, double c = 5.0);//每个参数的类型都要写清楚
    ~circle();
    double area();
    void print();
private:
    double x, y, r;
};
//function library
circle::circle(double a, double b, double c)
{
    x = a;
    y = b;
    c > 0 ? r = c : r = 5.0;
    cout << "circle object start:x=" << x << "\ty=" << y << "\tr=" << r << endl;
}
circle::~circle()
{
    cout << "circle object end:x=" << x << "\ty=" << y << "\tr=" << r << endl;
}
double circle::area()
{
    return pi * r * r;
}
void circle::print()
{
    cout << "x=" << x << "\ty=" << y << "\tr=" << r;
}
//创建column类
class column
{
public:
    column(double h = 5.0, double a = 5.0, double b = 5.0, double c = 5.0);
    ~column();
    double volume();
private:
    circle circle;//数据成员
    double height;
};
column::column(double h, double a, double b, double c)
    :circle(a, b, c)//为数据成员circle调用其构造函数,初始化列表
{
    h > 0 ? height = h : height = 5.0;
    cout << "coulumn object start : height = " << height << ",";
    circle.print();
    cout << endl;
}
double column::volume()
{
    return height * circle.area();
}
column::~column()
{
    cout << "column object end:height=" << height << ",";
    circle.print();
    cout << endl;
}
int main()
{
    column obj(2.3, 3.4, 4.5, 5.6);
    cout << "The volume of obj is" << obj.volume() << endl;
    return 0;
}
out:

circle object start : x = 3.4       y = 4.5   r = 5.6
coulumn object start : height = 2.3, x = 3.4       y = 4.5   r = 5.6
The volume of obj is226.482
column object end : height = 2.3, x = 3.4      y = 4.5   r = 5.6
circle object end : x = 3.4 y = 4.5   r = 5.6

⑤This指针

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;
/*
class test
{
public:
    test(int n = 0)
    {
        data = n;//直接访问
    }
    void print()
    {
        cout << "data=" << this->data << endl;//使用this指针访问
    }
private:
    int data;
};
*/
//静态成员函数没有维护this,访问非静态数据成员需要this
class test
{
public:
    test(int n = 0) { data = n; }
    test& setdata(int n)//返回值类型
    {
        data = n;
        return *this;
    }
    void print()
    {
        cout << "data=" << data << "!" << endl;
    }
private:
    int data;
};
int main()
{
    test obj;
    cout << "obj: ";
    obj.setdata(100).print();//函数连续调用,因为setdata返回的是test&类型
    return 0;
}
out:

obj: data=100!

⑥友元

Ⅰ友元函数

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;
//友元函数具有访问类的所有成员的权限,friend+函数原型
class triangle
{
    friend void seta(triangle& t, int n);//声明友元函数
public:
    triangle(int x = 5, int y = 5, int z = 5);
    void print();
private:
    int a, b, c;
};
triangle::triangle(int x, int y, int z)
{
    if (x + y > z && x + z > y && y + z > x)
    {
        a = x; b = y; c = z;
    }
    else
    {
        a = b = c = 5;
    }
}
void triangle::print()
{
    cout << "triangle:" << a << "," << b << "," << c << endl;
}
void seta(triangle& t, int n)
{
    t.a = n;//访问对象的私有成员
}
int main()
{
    triangle t;
    t.print();
    seta(t, 10);
    t.print();
    return 0;
}
out:

triangle:5, 5, 5
triangle : 10, 5, 5

Ⅱ友元类

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;
//一个类的友元类所有成员函数都有访问类的所有成员的权限,friend+class+类名
//友元的声明是单方面不传递的
class B;
class A
{
public:
    void setB(B& b, int m);
    void print(B& b);
};
class B
{
    friend class A;//声明友元,A可以访问B中所有成员
private:
    int data;
};
void A::setB(B& b, int m)
{
    b.data = m;
}
void A::print(B& b)
{
    //访问私有成员
    cout << "Thea private data of class B:" << b.data << endl;
}
int main()
{
    A a;
    B b;
    a.setB(b, 10);//调用A的成员函数修改类B的对象b的私有数据
    a.print(b);//调用A的成员函数访问b的私有数据
    
    return 0;
}
out:
Thea private data of class B :10

五、运算符重载

①原理

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;
//操作预定义数据对象的方式,自定义的对象操作方式,operator<运算符>
//.,*,::,?:,sizeof 不能被重载
class complex
{
public:
    complex(double = 0.0, double = 0.0);
    complex operator+(const complex&)const;//常量成员函数,即该函数不会修改类的任何成员变量。
    complex& operator=(const complex&);
    void print() const;
private:
    double real;
    double imaginary;
};
complex::complex(double r, double i)
{
    real = r; imaginary = i;
}
complex complex::operator+(const complex& operand2)const
{
    complex sum;
    sum.real = real + operand2.real;
    sum.imaginary = imaginary + operand2.imaginary;
    return sum;
}
complex& complex::operator=(const complex& right)
{
    real = right.real;
    imaginary = right.imaginary;
    return *this;
}
void complex::print()const
{
    cout << "(" << real << "," << imaginary << ")";
}
int main()
{
    complex x, y(4.3, 8.2), z(3.3, 1.1);
    x = y + z;//x.operator=(y.operator+(z));赋值运算符
    cout << "x=y+z:\n";
    x.print();
    cout << "="; y.print();
    cout << "+"; z.print();
    cout << endl;
    return 0;
}
out:

x = y + z :
    (7.6, 9.3) = (4.3, 8.2) + (3.3, 1.1)

②方式

Ⅰ成员函数重载

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;
//成员函数方式重载运算符
//重载!为成员函数
class mystring
{
public:
    mystring(const char* m = NULL);//默认构造函数
    ~mystring();
    //运算符重载成员函数原型
    bool operator!();
private:
    char* str;
};
mystring::mystring(const char* m)
{
    if (m == NULL)
    {
        str == NULL;
    }
    else
    {
        int len = strlen(m) + 1;//留一个放"\0"
        str = new char[len];
        strcpy_s(str, len, m);
    }
}
mystring::~mystring()
{
    if (str != NULL)
        delete[]str;
}
//实现运算符重载函数
bool mystring::operator!()
{
    if (str == NULL || strlen(str) == 0)
        return true;
    return false;
}
int main()
{
    mystring s1, s2("some string");
    if (!s1)
        cout << "s1 is NULL!" << endl;
    else
        cout << "s1 is not NULL!" << endl;
    if (!s2)
        cout << "s2 is NULL!" << endl;
    else
        cout << "s2 is not NULL!" << endl;
    return 0;
}
out:

s1 is NULL!
s2 is not NULL!

Ⅱ友元函数重载

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;

class mystring
{
public:
    mystring(const char* m = NULL);//默认构造函数
    ~mystring();
    friend bool operator!(mystring&s);
private:
    char* str;
};
mystring::mystring(const char* m)
{
    if (m == NULL)
    {
        str == NULL;
    }
    else
    {
        int len = strlen(m) + 1;//留一个放"\0"
        str = new char[len];
        strcpy_s(str, len, m);
    }
}
mystring::~mystring()
{
    if (str != NULL)
        delete[]str;
}
//实现运算符重载函数
bool operator!(mystring& s)
{
    if (s.str == NULL || strlen(s.str) == 0)
        return true;
    return false;
}
int main()
{
    mystring s1, s2("some string");
    if (!s1)
        cout << "s1 is NULL!" << endl;
    else
        cout << "s1 is not NULL!" << endl;
    if (!s2)
        cout << "s2 is NULL!" << endl;
    else
        cout << "s2 is not NULL!" << endl;
    return 0;
}
out:

s1 is NULL!
s2 is not NULL!

③单目与双目运算符重载

Ⅰ单目(目表示操作数)

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;

//重载运算符前自增++,返回值*this,类型complex&
class complex
{
public:
    complex(double = 0.0, double = 0.0);
    complex& operator++();//成员函数形式
    void print()const;
private:
    double real;
    double imaginary;
};
complex::complex(double r, double i)
{
    real = r;
    imaginary = i;
}
void complex::print()const
{
    cout << "(" << real << "," << imaginary << ")";
}
complex& complex::operator++()
{
    this->real += 1;
    return *this;
}
int main()
{
    complex y(4.3, 8.2), x;
    x = ++y;//x=y.operator++()
    cout << "y:"; y.print();
    cout << "\tx:"; x.print();
    cout << endl;
    return 0;
}
out:

y:(5.3,8.2)     x:(5.3,8.2)

Ⅱ流插入和流提取运算符的重载

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;

//如何实现用cout输出自定义类型的对象,重载<<和>>
class mystring
{
    //重载流插入和流提取函数
    friend ostream& operator<<(ostream& output, mystring& s);
    friend istream& operator>>(istream& input, mystring& s);
public:
    mystring(const char* m = NULL);
    ~mystring();
private:
    char* str;
};
mystring::mystring(const char* m)
{
    if (m == NULL)
        str == NULL;
    else
    {
        int len = strlen(m) + 1;
        str = new char[len];
        strcpy_s(str, len, m);
    }
}
mystring::~mystring()
{
    if (str != NULL)
        delete[]str;
}
//定义运算符<<重载函数
ostream& operator<<(ostream& output, mystring& s)
{
    output << s.str;
    return output;
}
//定义运算符>>重载函数
istream& operator>>(istream& input, mystring& s)
{
    char temp[1000];
    cin >> temp;
    if (s.str)delete[]s.str;//释放内存
    int len = strlen(temp) + 1;//"\0"
    s.str = new char[len];
    strcpy_s(s.str, len, temp);
    return input;
}
int main()
{
    mystring s1, s2;
    cout << "Please input two strings" << endl;
    cin >> s1 >> s2;
    cout << "Output is:" << endl;
    cout << "s1——" << s1 << endl << "s2——" << s2 << endl;
    return 0;
}
output:

Please input two strings
dager
fewre
Output is :
s1——dager
s2——fewre

Ⅲ双目

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;

//友元函数重载运算符+=
class mystring
{
    friend mystring& operator+=(mystring& x, mystring& y);
public:
    mystring(const char* m = NULL);
    ~mystring();
    void print() const;
private:
    char* str;
};
mystring::mystring(const char* m)
{
    if (m == NULL)
        str == NULL;
    else
    {
        int len = strlen(m) + 1;
        str = new char[len];
        strcpy_s(str, len, m);
    }
}
mystring::~mystring()
{
    if (str != NULL)
        delete[]str;
}
void mystring::print()const
{
    cout << str<

Ⅳ类型转化

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;
//类型转换,必须是类的非静态成员函数,不是友元函数,不能指定返回类型(其实已经指定了)
//operator+类型名 (int)obj等价于obj.operator int()
class Fraction {
private:
    int numerator;
    int denominator;

public:
    Fraction(int num, int den) : numerator(num), denominator(den) {}

    // 将 Fraction 类型转换为 double 类型
    operator double() const {
        return (double)numerator / denominator;
    }
};
int main()
{
    Fraction f(3, 4);
    double d = f; // 将 Fraction 类型转换为 double 类型
    cout << d << endl;
    return 0;
}
out:
0.75

六、继承派生多态

你可能感兴趣的:(ui,xhtml,前端,c++)