栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++类

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++类

定义

class<类名> {
private://第一段中可省略 
protected://在类和它的派生类中
public://
};

简单成员函数可以在类中定义,编译器作为内联函数处理。

成员函数:

1. 访问和修改数据成员

2. 传递信息

3.带有默认参数 this 指针(class_Type* const this)

this指针一旦被初始化(成员函数调用)就不能再被修改和赋值。

类的定义的同时成员函数也被定义(分配空间)

普通数据成员在创建对象时才被定义(分配空间)

访问

. ->

构造

带参数构造:

用途:1.引用 2.常量 3.包含

用法:类成员的初始化的顺序,按数据成员在类中的声明顺序进行初始化,与初始化成员列表中出现的顺序无关。

复制构造函数:

类名::类名(const 类名& 引用名,……);

用途:1.用一个类去给另一个类赋值 a=b;

2.函数具有类类型传值参数 3.函数返回值

深复制浅复制

#include
#include
using namespace std;
class Name {
public:
	Name(char* pn);
	~Name();
	Name(const Name& Obj);
	void setName(char*);
	void showName();
protected:
	char* pName;
	int size;
};
Name::Name(char* pn) {
	pName = new char[strlen(pn) + 1];
	if (pName != 0) strcpy_s(pName, strlen(pn) + 1, pn);
	size = strlen(pn);
}
Name::~Name() {
	delete[]pName;
	pName = NULL;
	size = 0;
}
Name::Name(const Name& Obj) {
	pName = new char[strlen(Obj.pName) + 1];
	//判断是否new新的资源
	if (pName != 0) strcpy_s(pName, strlen(Obj.pName) + 1, Obj.pName);
	size = Obj.size;
}
void Name::setName(char* pn) {
	//动态储存 改变存储的值,先清空再new
	delete[]pName;
	pName = new char[strlen(pn) + 1];
	if (pName != 0) strcpy_s(pName, strlen(pn) + 1, pn);
	size = strlen(pn);
}
void Name::showName() {
	cout << pName << endl;
}
int main() {
	char ans[10] = { "NoName" };
	char arr[10] = { "Tian" };
	Name Obj1(ans);
	Name Obj2 = Obj1;
	Obj1.setName(arr);
	Obj1.showName();
	Obj2.showName();
	return 0;
}

析构

撤销对象时,自动调用析构函数(有类就要析构)

析构顺序

#include
using namespace std;
class Location {
public:
	Location(int ii = 0, int jj = 0) {
		i = ii;
		j = jj;
	}
	Location(const Location& p);
	~Location() {}
private:
	int i;
	int j;
};
Location::Location(const Location& p) {
	i = p.i;
	j = p.j;
}
Location g() {
	Location A(1, 2);
	return A;
}
int main() {
	Location B;
	B = g();
	return 0;
}

创建对象B

创建局部对象A

复制初始化返回值的匿名对象

析构匿名对象

析构局部对象A

析构对象B

(栈)

类的其他成员

常成员

情景:在“只读”

1. 常数据成员

用法: 

1. 需要在构造时初始化  (每个对象都有相同的值)

class Class{
public:
    const int M;
    Class(): M(5){}
}

2. 带参构造(每个对象都有不同的值)

class Class{
public:
    const int code;
    Class(int num): code(num) {}
}

易错: 1.不可再成员函数中修改常数据成员。2.不能在类外面修改常数据成员

2. 常对象

情景:使对象在作用域中为“只读”

用法:

const Class(1,2);   //在定义对象的说明语句前加const 作为前缀。

易错:不可更改任意数据。

3.常成员函数

情景:不想改变

用法: 函数名 const

易错:常对象只能调用用常成员函数

const 函数重载

不能修改对象的数据成员,也不能访问类中没有const声明的非常成员函数

静态成员

静态数据

情况:同类共享一个数据(对象有共同的数据)

用法:static 类成员名

#include
using namespace std;
class Class{
public:
	static int Smem;
};
int Class::Smem=1;
int main(){
    Class c;
	cout< 

类名::静态数据

易错:受访问限制。

在声明类时不创建对象。

静态成员储存空间不依赖于都对象。

无论创建多少个对象,都不会创建静态数据成员

静态成员函数

情景:提供一个不依赖于类数据结构的共同操作(要操作静态数据成员就用)

用法:

#include
using namespace std;
class Class{
public:
	static int Smem;
	static int getSmem();
};
int Class::Smem=1;
int Class::getSmem(){
	return Smem;
}
int main(){
	Class c;
	cout< 

易错:没有this指针

只能操作静态数据成员

友元

友元可以访问类的所有成员,包括私有。

友元关系是非对称的,非传递的。

友元函数

用法:

#include
#include
using namespace std;
class Point{
public:
	Point(double i,double j){X=i;Y=j;}
	friend double Distance(Point& a,Point& b);
private:
	double X,Y;
};
double Distance(Point& a,Point& b){
	double dx=a.X-b.X;
	double dy=a.Y-b.Y;
	return sqrt(dx*dx+dy*dy);
}
int main(){
	Point p1(3.0,5.0),p2(4.,6.0);
	double d=Distance(p1,p2);
	cout< 

易错:不受声明位置(private ,protected,public)的影响

通过参数访问参数的私有成员

友元类

若F是A的友元类,则F类的所有成员函数都是A类的友元函数。

情景:友元类通常用来对数据操作和类之间传递信息的辅助类

继承
class 派生类名: 访问控制 基类名,访问控制 基类名 {
	数据成员和成员函数说明
};

易错:

class省略控制符默认为private

struct省略控制符默认为public

访问控制

易错:

就低

私有永远是私有

派生类中通过this指针调用基类的成员函数

this->基类成员函数

当基类成员函数被派生类成员函数屏蔽时

class A{
    out();
};
class B:public A{
  out();
};
B.A::out()
B.out()

不管类层次有多深,都必须从最高层的基类开始初始化。所以在设计类体系时,应该使基类尽量抽象,表达共性的东西,减少程序运行时间和空间的不必要浪费。

继承为私有访问,若想使用可以基类的成员函数,可以在父类

class A{
    out():
};
class B:private A{
    outAll(){
    out();
    }
};
访问声明

情景:使在派生类中原本不可见的成员变成可见的

(修改某一项成员的访问符)

用法:

class B:private A{
public: 
    A::out();
};

基类名::成员

易错:

1.仅调整名字的访问权限

数据成员时,不能加数据类型

成员函数时,不能加返回值和形参列表

2.不能改变基类的访问

在基类中是啥样就是啥样(只能调制和基类中的一样)

3.重载函数全改变

不同访问域的重载函数不能改变

派生类和基类中有同名函数不能改变

重名

数据成员

::

成员函数

相当于函数的重载(this指针不同)

通过指定类域的方法指示实参对象的地址类型

::

类成员的作用域从被说明开始,一直延申到他所有的派生类

派生类中的静态成员

静态成员在整个类体系中被共享,但访问性质不同

(共同,但访问性质不同)

基类的初始化

构造函数名(变元表):基类(变元表),数据成员(变元表),数据成员(变元表){}

先基类,再类对象成员,派生类

与形参初始式列表无关

const set

判断电话号对不对  姓名对不对

多继承

易错:

构造函数执行的顺序与定义派生类时指定的各个继承基类的顺序

重名

1.可以用作用域运算符,指定调用哪个基类继承的函数,即让this指针指向被操作的对象

2.现实使用类指针传递方式

虚继承

可能一个类被不止一次的继承

虚函数

函数重载编译三种判断方法:

函数参数特征

作用域

对象

(this指针)

基类指针引用派生类对象

只能引用基类成员。若引用派生类成员,需强制类型转换

派生类指针只能通过强制转换才能引用基类

this指针也可以强制转换成 (Father_Class*)this->父类成员函数

虚函数和动态联编

多态:用同一个基类指针指向虚函数

派生类和基类有同名函数,基类指针在指向不同派生类对象时,可以通过this指针获得不同对象的数据成员,但因为是基类指针所以,只能调用基类的成员函数

易错:

一旦一个成员函数被说明成了虚函数,无论经历多少派生类层次都是虚函数。派生类也是基类。

虚函数必须是类的成员函数。

不能将说明为虚函数,但虚函数可以是另一个类的友元

析构可以是虚,构造不行。

虚函数重载

函数名,返回类型,参数个数,参数类型和顺序  完全相同

仅函数名相同,会失去虚特性

原因:虚函数是仅由this指针类型区分的接口函数,c++的虚特性 仅负责在程序运行时把基类this

指针的关联类型=》当前指向对象的类类型,而不改变其他参数的性质。

虚析构函数

用基类指针创建派生类的动态对象,只能用虚析构函数

用了没坏处

纯虚函数与抽象类

至少有一个纯虚函数的的基类叫做抽象类

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

定义了纯虚函数实现的派生类叫做具体类

1.抽象类只能用作其他类的基类

2.抽象类不能建立对象

3.抽象类不能做参数类型。函数返回类型,显式类型转换

可以说明抽象类的引用和指针

异质链表

用容器存基类指针

new派生类

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/982154.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号