可以做护考题目的网站,个人网站 建设方案书,网站实现搜索功能,建设银行网站无法打开类和对象#xff08;提高#xff09;
1、定义一个类 关键字class 6 class Data1
7 {
8 //类中 默认为私有
9 private:
10 int a;//不要给类中成员 初始化
11 protected://保护
12 int b;
13 public://公共
14 int c;
15 //在类的内部 不存在权限之分
16 void showData(void)…类和对象提高
1、定义一个类 关键字class 6 class Data1
7 {
8 //类中 默认为私有
9 private:
10 int a;//不要给类中成员 初始化
11 protected://保护
12 int b;
13 public://公共
14 int c;
15 //在类的内部 不存在权限之分
16 void showData(void)
17 {
18 couta b cendl;
19 }
20 };2、成员函数在类外实现
class Student
{
private:int age;
public:void setAge(int a);void getAge(void);
};void Student::setAge(int a)
{agea;
}void Student::getAge()
{coutageendl;
}
3、类在其他文件实现 头文件定义类 cpp实现类的成员函数
egstudent.h中
#ifndef STUDENT_H
#define STUDENT_Hclass Student
{
private:int age;
public:void setAge(int a);void getAge(void);
};#endif // STUDENT_H
student.cpp中
#include student.h //引入头文件
#includeiostream
using namespace std;void Student::setAge(int a)
{agea;
}void Student::getAge()
{coutageendl;
}
main.cpp实现student类
#include iostream
#include cstring
#includestudent.h
using namespace std;int main(){
Student stu1;
stu1.setAge(18);
stu1.getAge();return 0;
}
构造函数
1、如果用户不提供构造函数 编译器会自动 提供一个无参的空的构造函数。 2、如果用户提供构造函数 编译器会自动 屏蔽默认无参的构造 class Data{
int mA;public:
Data(){mA 0;cout无参构造函数endl;
}Data(int a)
{mA a;cout有参构造函数endl;}
};void test01(){//隐式调用无参构造(推荐)Data ob1;//显示调用无参构造Data ob2Data();//隐式调用有参构造(推荐)Data ob3(10);//显示调用有参构造Data ob4Data(20);//如果构造函数只有一个参数 可能发生 构造函数的隐式转换知道就行Data ob5 30;//Data ob5(30);//匿名对象当前语句结束 对象就要被释放Data();//调用无参Data(40);//调用有参coutob4.mAendl;}析构函数
当对象生命周期结束的时候 系统自动调用析构函数。 函数名和类名称相同在函数名前加~没有返回值类型没有函数形参。不能被重载 先调用析构函数 再释放对象的空间。
class Data1{public:int mA;public://无参构造函数Data1(){mA0;cout无参构造函数endl;}//有参构造函数Data1(int a){mAa;cout有参构造函数 mAmAendl;}//析构函数~Data1(){cout析构函数 mAmAendl;}};一般情况下空的析构函数就足够。但是如果一个类有指针成员这个类必须 写析构函数释放指针成员所指向空间。
#include iostream
#includestring.h
#includestdlib.h
using namespace std;class Data1{
private:char *name;public:Data1(char *str){name(char *)calloc(1,strlen(str)1);strcpy(name,str);}//释放指针空间~Data1(){cout析构函数 namenameendl;if(name!NULL){free(name);nameNULL;}}};int main(int argc, char *argv[])
{
Data1(张三);return 0;
}
拷贝构造函数
拷贝构造本质是构造函数 拷贝构造的调用时机旧对象 初始化 新对象 才会调用拷贝构造。
#include iostream
#includestring.h
#includestdlib.h
using namespace std;class Data1{public:int numA;
//拷贝函数
Data1(const Data1 ob){//ob就是旧对象的别名numAob.numA;//一旦实现 了拷贝构造 必须完成赋值动作cout调用拷贝函数endl;
}
Data1(int a){numAa;
}};int main(int argc, char *argv[])
{
Data1 ob1Data1(10);
Data1 ob2ob1;
coutob2:numAob2.numAendl;return 0;
}
如果用户不提供拷贝构造 编译器会自动提供一个默认的拷贝构造完成赋值动作–浅拷贝
拷贝构造 和 无参构造 有参构造的关系: 如果用户定义了 拷贝构造或者有参构造 都会屏蔽无参构造。 如果用户定义了 无参构造或者有参构造 不会屏蔽拷贝构造
拷贝构造函数几种调用方式
1、旧对象给新对象初始化调用拷贝构造
Data4 ob1(10);
Data4 ob2 ob1;//调用拷贝构造2、给对象取别名 不会调用拷贝构造
Data4 ob1(10);
Data4 ob2 ob1;//不会调用拷贝构造3、普通对象作为函数参数 调用喊谁时 会发生拷贝构造
void fun1(Data1 ob){//Data1 obobAcoutob.numAendl;
}int main(int argc, char *argv[])
{Data1 obA(10);fun1(obA);return 0;
}
4、函数返回值普通对象 Visual Studio会发生拷贝构造Qtcreater,linux不会发生Visual Studio会发生拷贝构造 深拷贝
1、默认的拷贝构造 都是浅拷贝。 2、如果类中没有指针成员 不用实现拷贝构造和析构函数。 3、如果类中有指针成员 必须实现析构函数释放指针成员指向的堆区空间必须实现拷贝构造完成深拷贝动作。
#include iostream
#includestring.h
#includestdlib.h
using namespace std;class Data1{public:char *name;//有参构造
Data1(char *n){name(char *)calloc(1,strlen(n)1);strcpy(name,n);
}~Data1(){cout析构函数 namenameendl;
if(name!NULL){free(name);nameNULL;
}}
//深拷贝
Data1(const Data1 ob){
name(char *)calloc(1,strlen(ob.name)1);
strcpy(name,ob.name);
}};int main(int argc, char *argv[])
{Data1 obA(hello world);
Data1 obobA;return 0;
}
初始化列表
成员对象一个类的对象作为另一个类的成员 如果类中想调用成员对象的有参构造 必须使用初始化列表。 class DataA{
public :int a;
public:DataA(){coutA的无参构造endl;}DataA(int num){anum;coutA的有参构造endl;}~DataA(){coutA的析构函数endl;}
};class DataB{
public:int b;DataA ob;
public:DataB(){coutB的无参构造endl;}DataB(int num,int numa){bnum;ob.anuma;coutB的有参构造endl;}~DataB(){coutB的析构函数endl;}
};int main(int argc, char *argv[])
{DataB ob(10,20);return 0;
}打印结果
A的无参构造
B的有参构造
B的析构函数
A的析构函数类会自动调用成员对象的无参构造。 类想调用成员对象 有参构造 必须使用初始化列表。
使用初始化列表调用成员对象的有参构造 DataB(int num,int numa):ob(numa)//修改B的有参构造{bnum;coutB的有参构造endl;}A的有参构造
B的有参构造
B的析构函数
A的析构函数对象数组
对象数组本质是数组 数组的每个元素是对象
class DataA{
public :int a;
public:DataA(){coutA的无参构造endl;}DataA(int num){anum;coutA的有参构造endl;}~DataA(){coutA的析构函数endl;}
};int main(int argc, char *argv[])
{//对象数组 每个元素都会自动调用构造和析构函数//对象数组不会自动初始化 每个元素 调用无参构造
// ataA array[5];//对象数组的初始化 必须显示使用有参构造 逐个元素初始化DataA array[5]{DataA(1),DataA(2),DataA(3),DataA(4),DataA(5)};int lensizeof(array)/sizeof(array[0]);for(int i0;ilen;i){coutarray[i].a ;}coutendl;return 0;
}
A的有参构造
A的有参构造
A的有参构造
A的有参构造
A的有参构造
1 2 3 4 5
A的析构函数
A的析构函数
A的析构函数
A的析构函数
A的析构函数explicit函数
explicit防止构造函数隐式转换
什么是隐式转换
class DataA{
public :int a;
public:DataA(){coutA的无参构造endl;}DataA(int num){anum;coutA的有参构造endl;}~DataA(){coutA的析构函数endl;}
};int main(int argc, char *argv[])
{DataA ob10;//隐式转换 DataA obData(10);return 0;
}加上explicit关键字防止隐式转换【new和delete 堆区空间操作
class DataA{
public :int a;
public:DataA(){coutA的无参构造endl;}explicit DataA(int num){anum;coutA的有参构造endl;}~DataA(){coutA的析构函数endl;}
};int main(int argc, char *argv[])
{DataA ob10;//errorreturn 0;
}new和delete 堆区空间操作
1、new和delete操作基本类型的空间
int main(int argc, char *argv[])
{int *pnew int(5);cout*p*pendl;delete p;return 0;
}区别 new 不用强制类型转换(malloc返回的类型是(void *)) new在申请空间的时候可以 初始化空间内容
new 申请基本类型的数组
int main(int argc, char *argv[])
{int *pnew int[5]{1,2,3,4,5};for(int i0;i5;i){coutp[i]endl;}delete []p;//delete 数组要加上[]return 0;
}2、new和delete操作类
malloc不会调用构造函数 free不会调用析构函数 new 会调用构造函数 delete调用析构函数
class DataA{
public :int a;
public:DataA(){coutA的无参构造endl;}explicit DataA(int num){anum;coutA的有参构造endl;}~DataA(){coutA的析构函数endl;}
};int main(int argc, char *argv[])
{
DataA *p1new DataA();
DataA *p2new DataA();
DataA *arraynew DataA[5]{DataA(1),DataA(2),DataA(3),DataA(4),DataA(5)};delete p1;//delete
delete p2;
delete[]array;//释放数组的空间return 0;
}静态成员
类的对象 拥有独立的 普通成员数据。 static 修饰的成员 叫 静态成员
class Data{static int a;//静态成员数据static void func()//静态成员函数{}①静态成员数据
static修饰的静态成员 属于类而不是对象。所有对象共享 一份 静态成员数据 static修饰的成员 定义类的时候 必须分配空间。 static修饰的静态成员数据 必须类中定义 类外初始化。
class DataA{
public :int a;static int b;
public:DataA(){coutA的无参构造endl;}DataA(int num){anum;coutA的有参构造endl;}
};int DataA::b100;//类外初始化int main(int argc, char *argv[])
{coutDataA::bendl;//100DataA *obnew DataA();coutob.bendl;//100ob.b200;coutDataA::bendl;//200return 0;
}静态成员数据统计对象个数
#include iostreamusing namespace std;class DataA{
public :int a;static int count;
public://无参构造DataA(){count;}//有参构造DataA(int num){anum;count;}//拷贝构造DataA(const DataA ob){aob.a;count;}//析构函数~DataA(){count--;}
};int DataA::count0;//类外初始化int main(int argc, char *argv[])
{
DataA oba;
DataA obb(10);
DataA obcoba;
cout对象个数为DataA::countendl;return 0;
}
静态成员函数
静态成员函数 是属于类 而不是对象所有对象共享
1、静态成员函数可以直接通过类名称访问
2、静态成员函数内只能操作静态成员数据
单例模式
单例模式的类只能实例化一个对象
1、构造函数私有化
2、定义一个私有的对象指针保存唯一的实例地址
#include iostreamusing namespace std;class SingleTon{//构造函数私有化
private:SingleTon(){count0;cout构造endl;}~SingleTon(){cout析构函数endl;}SingleTon(const SingleTon ob){count0;cout拷贝构造endl;}private:static SingleTon *const p;int count;public:static SingleTon *getSingleTon(void){return p;}void printStirng(char *str){count;cout当前第count次任务打印strendl;}};
SingleTon *const SingleTon::pnew SingleTon;int main(int argc, char *argv[])
{SingleTon *pSingleTon::getSingleTon();p-printStirng(hello);SingleTon *p2SingleTon::getSingleTon();p2-printStirng(hello);return 0;
}
类的存储结构
类的成员函数和静态变量不占类的内存空间 const修改成员函数为只读
#include iostream
#includestring
#includestdlib.h
using namespace std;class DataA{
public :int a;mutable int b;//mutable修饰的成员变量可以修改public:void printString(void) const{//const修饰成员函数为只读
// this-a100;//在打印函数中修改成员变量 errorcoutaaendl;this-b100;coutbbendl;}DataA(int a,int b){this-aa;this-bb;}
};int main(int argc, char *argv[])
{DataA obDataA(10,20);ob.printString();return 0;
}
友元
1、普通全局函数作为类的友元
#include iostream
#includestringusing namespace std;class Room{friend void visit(Room room);//friend关键字
private:string bedRoom;//卧室
public:string setingRoom;//客厅
public://构造函数Room(string bedRoom,string setingRoom){this-bedRoombedRoom;this-setingRoomsetingRoom;}};//普通的全局函数
void visit(Room room){cout访问了room.setingRoomendl;cout访问了room.bedRoomendl;
}int main(int argc, char *argv[])
{Room room(张三卧室,张三客厅);visit(room);return 0;
}
2、类的某个成员函数 作为另一个类的友元
#include iostream
#includestring.husing namespace std;class Room;//先声明class goodGay{
public:void visit01(Room room);//先在类中声明类外实现否则之前只声明了Room并没有声明Room中的成员所以访问不了void visit02(Room room);
};class Room{friend void goodGay::visit02(Room room);//将类中成员函数声明为友元
private:string bedRoom;//卧室
public:string setingRoom;//客厅
public://构造函数Room(string bedRoom,string setingRoom){this-bedRoombedRoom;this-setingRoomsetingRoom;}};//类外实现
void goodGay::visit01(Room room){cout李四访问了room.setingRoomendl;}void goodGay::visit02(Room room){cout好基友张八访问了room.setingRoomendl;cout好基友张八访问了room.bedRoomendl;}int main(int argc, char *argv[])
{Room room(张三卧室,张三客厅);goodGay ob;ob.visit01(room);ob.visit02(room);return 0;
}
3、 整个类作为友元
这个类的所有成员函数 都可以访问另一个类的私有数据
#include iostream
#includestring.husing namespace std;class Room;//先声明class goodGay{
public:void visit01(Room room);//先在类中声明类外实现否则之前只声明了Room并没有声明Room中的成员所以访问不了void visit02(Room room);
};class Room{friend class goodGay;private:string bedRoom;//卧室
public:string setingRoom;//客厅
public://构造函数Room(string bedRoom,string setingRoom){this-bedRoombedRoom;this-setingRoomsetingRoom;}};void goodGay::visit01(Room room){cout李四访问了room.setingRoomendl;}void goodGay::visit02(Room room){cout好基友张八访问了room.setingRoomendl;cout好基友张八访问了room.bedRoomendl;}int main(int argc, char *argv[])
{Room room(张三卧室,张三客厅);goodGay ob;ob.visit01(room);ob.visit02(room);return 0;
} 注意 1友元关系不能被继承。 2友元关系是单向的类A是类B的朋友但类B不一定是类A的朋友。 3友元关系不具有传递性。类B是类A的朋友类C是类B的朋友但类C不一定是类A的朋友 设计动态数组类
Array.h
#ifndef ARRAY_H
#define ARRAY_H
class Array{
private:int *arr;//存放首地址元素int capacity;//容量int size;//大小public:Array();Array(int capacity);Array(const Array ob);~Array();int getCapacity() const;//get容量int getSize() const;//getSizevoid printArray(void);//打印数组void pushBack(int elem);//从尾部插入数据void popBack(void);//删除尾部元素int at(int pos);//获取元素,并返回引用类型};#endif // ARRAY_H
array.cpp
#include array.h
#include string.h
#include iostream
using namespace std;
Array::Array(){capacity5;size0;arrnew int[capacity];memset(arr,0,sizeof(int)*capacity);}
Array::Array(const Array ob){capacityob.capacity;sizeob.size;arrnew int[capacity];memcpy(arr,ob.arr,sizeof(int)*capacity);}
Array::~Array(){if(arr!NULL){delete[]arr;arrNULL;}
}
int Array::getCapacity()const{return capacity;
}
int Array::getSize()const{return size;
}
void Array::pushBack(int elem){if(sizecapacity){int *tempnew int[2*capacity];memcpy(temp,arr,sizeof(int)*capacity);delete[]arr;arrtemp;capacity2*capacity;}arr[size]elem;return;
}
void Array::popBack(){if(size0){cout容量为空endl;}else{size--;}return;
}
int Array::at(int pos){if(pos0||possize){cout访问违法内存endl;exit(-1);}return arr[pos];
}
void Array::printArray(void){for(int i0;isize;i){coutarr[i] ;}coutendl;
}
main.cpp
#include array.h
#include iostream
using namespace std;int main(int argc, char *argv[])
{
Array array;
array.pushBack(10);
array.pushBack(20);
array.pushBack(30);
array.pushBack(40);
array.printArray();
array.at(2)100;
array.printArray();return 0;
}