IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C/C++基础(自用)-04 -> 正文阅读

[C++知识库]C/C++基础(自用)-04

类与对象

定义

公有成员通常为成员函数
私有成员为数据成员
class 类名
{
	public://访问权限:公有
		<数据成员或成员函数的说明>;
	private://私有
		<成员函数或数据成员的说明>;
	protected://保护
		<成员函数或数据成员的说明>;
};
<各个成员函数的实现>;

注:
1.成员函数可直接操作数据成员;若在函数内部定义与数据成员同名的变量,则操作的是函数内的局部变量
2.类体中不允许对数据成员的初始化
3.自身类的对象不可以作为自己的成员
4.类体内只给出成员函数的说明未给出具体实现时,则在实现部分成员函数名前需要加类名与作用域运算符(::)
在这里插入图片描述

对象

定义

类名 对象名表;

加入Circle是前面已定义过的圆类,则可以定义为

Circle c1,*p,c[5]; //*p为对象指针,c[5]为对象数组

对象的访问

对象成员的访问

对象.数据成员
对象.成员函数(参数表)

通过指向对象的指针访问成员

对象指针->数据成员
(*对象指针).数据成员
对象指针->成员函数(参数表)
(*对象指针).成员函数(参数表)
//定义一个circle类
class Circle
{
	private:
		double x,y,r;
	public:
		void set(double x1,double y1,double r1); //类内没有给出成员函数的具体实现
		void print();
		double getarea();
		double getgirth();
};
void Circle :: set(double x1,double y1,double r1)
{
	x = x1;
	y = y1;
	r = r1;
}
double Circle :: getarea()
{	return 3.14*r*r;} 
//.....(其他函数省略)
int main()
{
	Circle c;//定义一个对象
	c.set(0,0,2);
	c.print();
	cout<<c.getarea()<<endl;
	cout<<c.getgirth()<<endl;
	return 0;
}

【问题】:定义一个职工类Staff,包含工号与工资两个数据成员以及设置和输出施工信息的功能,同时通过对象和指针对该类进行测试

#include<iostream>
#include<string.h>
using namespace std;

class Staff {
	private:
		char no[7];
		float money;
	public:
		void display()
		{
			cout << no << ":" << money << endl;
		}
		void set(char n[], float w)
		{
			strcpy(no,n);
			money = w;
		}
};
int main()
{
	Staff s, * s1;
	s.set("10109",3526);
	s.display();
	s1 = new Staff;//需要为对象指针申请内存空间
	s1->set("090303", 4003);
	s1->display();
	system("pause");
	return 0;
}

构造函数与析构函数

构造函数

定义一个对象时,对系统而言就意味这要创建这个对象,这需要构造函数的指出;
另外,对象也可以初始化,这也需要构造函数的支持
在这里插入图片描述
特点

  • 是类的一个特殊成员函数,创建对象时需要调用该函数;
  • 在创建对象时由系统自动调用,程序中不能直接调用,
  • 函数名同类名,不能指定函数类型,可以带参数
  • 可定义多个参数个数不同的构造函数,即构造函数允许重载
    重载是c++允许在同一范围中声明几个功能类似的同名函数,但这些同名函数的形式参数个数或类型不同

缺省构造函数

<构造函数名>() // 必须无参,无函数体
{
}
//若是用户没有定义过构造函数,系统会自动生成确省的构造函数

拷贝构造函数

该函数只有一个参数,且是对某个对象的引用。

作用:
1.用已知的对象初始化被创建的同类对象
2.做函数的形参以及返回值时创建对象

如:前例的Circle类中隐含了缺省拷贝构造函数

Circle(Circle &c)
{x=c.x;y=c.y;r=c.r}

可以有定义

Circle c1(0,0,2),c2(c1);//用c1给c2赋值,自动调用拷贝构造函数

问题:定义一个复数类,具有初始化复数(通过构造函数),输出复数以及求了两个复数和的功能
在这里插入图片描述

析构函数

当对象的生存期结束时,通过析构函数释放对象
  • 当一个对象被定义在函数体内,则当该函数结束时,该对象的析构函数被自动调用,对象占用的空间被释放;
  • 若一个对象是使用new运算符被动态创建,则在执行delete运算时,析构函数将会被自动调用,该对象占用的空间被释放;

特点:
1.是一个特殊的成员函数,用于释放对象,生存期结束时由系统自动调用,也可由用户调用
2.函数名同类名,前面加字符"~",不指定类型,无参
3.不可重载,即一个类只能定义一个析构函数。

缺省析构函数
若是用户没有定义过析构函数,系统会自动生成缺省形式的析构函数

~<析构函数名>()
{
}

类的特殊成员

常成员

保护数据和对象不被修改,可声明为常数据成员或常对象
与这些长数据或常对象相关的操作又需要常成员函数的支持

常数据成员

定义某数据成员时,类型前加const声明,可使得该数据受到强制保护。
在这里插入图片描述

常成员函数

不能修改数据成员的值,用于读取常对象的值

类型说明符 函数名(参数表) const

注:
1.不修改对象数据成员的成员函数才能声明为常成员函数;
2.构造函数和析构函数不能声明为const;
3.除构造函数和析构函数之外,只有常成员函数可以操作常对象
在这里插入图片描述

静态成员

为了解决数据共享问题,类中支持静态成员的定义,分为静态数据成员和静态函数

静态数据成员

数据成员定义前加关键字static说明:静态成员

  • 静态成员是类的成员,在内存中只存贮一次,被所有对象共享
  • 初始化的位置需放在类体外,初始化语句前不加static和访问权限修饰符
数据类型 类名::静态数据成员=

静态成员函数

静态成员函数:成员函数声明前加static说明
调用形式

类名::静态成员函数名(参数表)

在这里插入图片描述

继承与多态

继承关系与派生类的定义

通过继承,原有类为基类(父类),新类为派生类(子类)
C++支持单继承与多继承
在这里插入图片描述

单继承

一个派生类只有一个父类的继承关系

class 派生类名:继承方式 基类名
	{派生类新定义成员};
  • 继承方式:public、private、protected
  • 派生类继承基类中除构造函数与析构函数以外的所有成员;
  • 继承方式的不同决定了派生类对基类成员访问权限的不同,实际应用中都采用公有继承

** 问题**:假设Circle是已经定义过的类,从该类派生定义一个圆柱体类,具有数据成员的输入与输出功能

定义的圆类

class Cricle 
{
private:
	double r;
public:
	void set(double r1)
	{
		r = r1;
	}
	void print()
	{
		cout << "半径:" << r << endl;
	}
};

定义的Cylinder类

class Cylinder :public Cricle
{
private://在private中定义派生类的新成员
	double h; 
public:
	void print()
	{
		Cricle::print(); //调用基类中同名函数,需要指出基类名
		cout << "圆柱高:" << h << endl;
	}

	void set(double r1, double h1)
	{
		Cricle::set(r1);
		h = h1;
	}

在这里插入图片描述

基类名::数据成员名;
基类名::成员函数名(参数表);

派生类对基类的访问

访问

问题:我们在上述的派生类Cylinder中增加求圆柱体体积的成员函数volume,如何实现?
在这里插入图片描述

构造函数与析构函数

  • 派生类的构造函数要给自己的数据成员初始化,同时也要调用基类的构造函数使得基类的数据成员初始化;
  • 当对象被删除时,派生类的析构函数被执行,同时基类的析构函数也将被调用
派生类名(总参数表):基类构造函数(参数表1)
{<派生类中数据成员初始化>};
  • 基类中若有缺省的构造函数或没定义构造函数,则派生类构造函数的定义中可省略对基类构造函数的调用,而隐式调用缺省构造函数
  • 基类构造函数中,只有有参的构造函数,则派生类构造函数中必须调用基类构造函数
  • 派生类构造函数的调用顺序为先基类,再派生
  • 派生类析构函数的执行顺序为先派生再基类

问题:在原有职工类的staff的基础上派生一个子类staff1,该类中增加工龄成员及按工龄涨工资的函数,每满10年涨80元

#include<iostream>
#include<string.h>
using namespace std;

class Staff
{
private:
	char no[7];
	float wage;
public:
	void display()
	{
		cout << no << ":"<< wage << endl;
	}
	Staff(char n[], float w)
	{
		cout << "Staff构造函数被调用\n";
		strcpy(no,n);
		wage = w;
	}
};

class Staff1 :public Staff
{
private:
	int wt;
public:
	Staff1(char n[], float w, int t) :Staff(n, w)
	{
		cout << "Staff1构造函数被调用\n";
		wt = w;
	}
	double addwage()
	{
		return(wt / 10 * 80);
	}
	void display()
	{
		Staff::display();
		cout << wt << "," << addwage() << endl;
	}
};

int main()
{
	Staff1 s("110109", 3526, 11);
	s.display();
	system("pause");
	return 0;
}

在编写程序时,遇到了这么一个错误
在这里插入图片描述
在C++ 中,非定义与初始化时,双引号返回一个指向变量的地址,在上述主函数代码中Staff s("110109") 代表的是指向变量110109的地址,所以我们在定义字符串数组阶段,采用指针变量的形式进行定义,就解决了等号两边变量=与变量类型相同的值的问题。具体参考自用01中的字符指针一节。
因此在定义Staff类保存工号的类型应定义为指针变量char *n;(我们尽量定义数组和使用数组时采用指针变量)

基于虚函数的多态性

向不同的对象发送同一个消息,不同对象会产生不同的响应,在程序中发出消息代表调用函数,而响应代表函数实现通过多态性可实现“一个接口多种方法”。形式有:

  • 函数重载
  • 运算符重载
  • 基于虚函数的多态性

函数重载与运算符重载都属于静态多态,而使用虚函数实现一种接口多种方法的是动态多态

虚函数

一种接口,多种方法

virtual 类型说明符 函数名(参数表)

虚函数使程序在运行阶段具体决定调用哪个类的方法(函数),而非按编译阶段绑定的基类方法执行,这成为动态联编
在这里插入图片描述
在这里插入图片描述

  • 基类中有说明的虚函数,可以只将基类中的成员函数显式地说明为虚函数,而派生类中的同名函数也隐含为虚函数;
  • 派生类的虚函数应与基类中的虚函数具有相同的名称、参数个数以及参数类型;
  • 调用虚函数操作的只能是对象指针或对象引用,否则仍为静态联编

抽象类

抽象类带有纯虚函数的特殊类,主要作用是将有关的子类组织在一个继承层次结构中,由它来为他们提供一个公共的根

纯虚函数

virtual 类型 函数名(参数表)=0;

抽象类的特点

  • 只能用作其他类的基类,不能创建抽象类对象;
  • 可定义抽象类指针与引用,指向或引用其派生类,进而实现多态性
  • 不能用作参数类型、函数返回类型或强制转换的类型。
#include<math.h>
#include<iostream>
using namespace std;

class base
{
protected:
	int x, y;
public:
	virtual void set(int i, int j = 0)
	{
		x = i;
		y = j;
	}
	virtual void disp() = 0;
};

class square :public base
{
public:
	void disp()
	{
		cout << x * x << endl;
	}
};

class cube :public base
{
public:
	void disp()
	{
		cout << x * x * x << endl;
	}

};

class pow1 :public base
{
public:
	void disp()
	{
		cout << pow((double)x, y);
	}
};

int main()
{
	base* ptr; square B; cube C; pow1 D;
	ptr = &B;
	ptr->set(5);
	ptr->disp();
	ptr = &C;
	ptr->set(6);
	ptr->disp();
	ptr = &D;
	ptr->set(3,4);
	ptr->disp();
	system("pause");
	return 0;
}

在这里插入图片描述
可以将上述主函数的代码写在一个方法中
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:13:43  更:2022-10-17 12:15:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 8:02:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码