C++(二)
- 类和对象
- C中的结构体和C++中的结构体有什么区别
- C++中的结构体和类有什么区别
- 访问限定符
- 类的定义
- 对象
- 类与对象之间的关系
- 封装
- this指针
- 类中特殊的成员函数
- 构造函数
- 默认构造函数
- 普通构造函数
- 拷贝构造函数
- 浅拷贝
- 深拷贝
- 析构函数
类和对象
什么是结构体:描述一类事物相关属性的集合,是一种自定义的数据类型
C中的结构体和C++中的结构体有什么区别
- c中结构体不能有函数,而c++的结构体可以有函数
- c中空结构体的大小为0,而c++的空结构体的大小为1
C++中的结构体和类有什么区别
- c++结构体的关键字是struct,类的关键字是class
- c++结构体定义的叫做变量,类定义的叫做对象
- 如果没有写访问限定符,c++结构体默认是共有的,类默认是私有的
- c++中的空结构体和空类的大小都是1
访问限定符
访问限定符
public:共有的,在类内可以访问,在类外也可以访问
private:私有的,在类内部可以访问,在类的外部不能访问
protected:受保护的,在类内部可以访问,在内外不能访问
类的定义
class 类名
{
//访问限定符
public:
private:
protected:
//成员
成员变量:属性
成员函数:行为
};
对象
用类这种自定义数据类型定义的变量就叫做对象
类与对象之间的关系
类是抽象的对象,对象是类的具体化
封装
面向对象编程的特点:封装、继承、多态、抽象
把一类事物共同的的属性和行为提取出来(抽象),将提取出来的内容用一个自定义的数据类型保存起来,将该隐藏的隐藏,该暴露的暴露出来
隐藏:属性
暴露:行为
- 每一个对象都有一份自己的成员变量
- 所有的对象公用一得成员函数
- 类的大小是由成员变量来决定,遵循字节对齐
- 类本身不占内存空间,但是有大小,只有在实例化对象的时候才会分配内存空间
#include <iostream>
using namespace std;
//定义类
//class 类名
//{
// //访问限定符:
//public://共有的,在类内部可以访问,在类外部也可以访问
//private://私有的,在类内部可以访问,在类的外部不可以访问
//protected://受保护的,在类内部可以访问,在类的外部不可以访问
// //成员
// 成员变量:属性
// 成员函数:行为
//};
class Phone
{
public:
//行为
void call()
{
cout << "打电话中..." << endl;
}
void sendMessage()
{
cout << "发短信" << endl;
}
void playGames()
{
cout << "打游戏" << endl;
}
void setPrice(int _price)
{
price = _price;
}
void show()
{
cout << "价格为:" << price << endl;
}
private:
//属性
string brand;
string color;
int price;
int size;
protected:
};
int main()
{
//类的大小
cout << sizeof(string) << endl;//28
cout << sizeof(Phone) << endl;//类的大小是由成员变量的大小来决定的
//实例化对象
Phone phoneA;
phoneA.setPrice(3999);
phoneA.show();
Phone phoneB;
phoneB.setPrice(4999);
phoneB.show();
phoneA.show();
return 0;
}
this指针
- 哪个对象调用类中的成员函数,this指针指向的就是哪个对象的地址
- 每一个非静态成员函数都隐藏了一个this指针,this指针的格式
类名 * const this;
备注:this指针是成员函数中的第一个参数
- 当类中的成员函数要操作成员变量时,当形参的名称和成员变量的名称一样的时候,我们可以用this指针来避免因为名字一样而造成的数据混乱
#include <iostream>
using namespace std;
//封装手机的类
class Phone
{
public:
void call();
void sendMessage();
void playGames();
void setPrice(int price);
private:
string brand;
string color;
int price;
protected:
};
//返回值的类型 类名::成员
void Phone::call()
{
cout << "打电话" << endl;
}
void Phone::sendMessage()
{
cout << "发短信" << endl;
}
void Phone::playGames()//void Phone::playGames(Phone *const this)
{
cout << "打游戏" << endl;
}
void Phone::setPrice(int price)//void Phone::setPrice(Phone * const this,int_price)
{
this->price = price;
}
int main()
{
//实例化对象 类名 对象名;
Phone phoneA;
phoneA.setPrice(3999);//phoneA.setPrice(&phoneA,3999)
Phone phoneB;
return 0;
}
类中特殊的成员函数
构造函数
作用:
在创建对象的时候,给对象分配内存空间并对成员变量进行初始化
什么时候调用:
在创建对象的时候
谁调用:系统调用
如果没有自定义构造函数,系统会自动生成一个无参的构造函数
如果自定义了构造函数,调用的时候就执行的是自定义的构造函数
构造函数的格式:与类同名,没有返回值,参数不确定(构造函数是可以重载的)
类名(形参列表)
{
;
}
默认构造函数
- 无参的,自己写的,编译器自动生成
- 有参数并且所有的参数都有默认值
- 一个类中最多可以有多少个默认构造函数?只能有一个
自己没有写,在创建对象的时候,编译器帮我们自动生成的一个无参的构造函数;
自己写的,无参的构造函数,也是默认构造函数;编译器就不会再生成了!!!
自己写的,有参数的构造函数,并且所有参数都有默认值!!!
普通构造函数
相当于被重载出来
有2个或者2个以上参数的,并且不是所有参数都有默认值!
拷贝构造函数
什么时候调用:
用一个已经存在的对象给正在创建的对象赋值的时候
谁调用:系统
如果没有自定义拷贝构造函数,系统自动生成一个浅拷贝构造函数
如果自定义了拷贝构造函数,系统执行自定义的拷贝构造函数
拷贝构造函数的格式:与类名相同,无返回值,有且仅有一个参数(类类型的应用)
类名(类名 & 引用名)
{
}
有一个参数并且这个参数是类类型的引用! 如果自己不写,编译器会自动生成一个
浅拷贝构造函数,如果要进行深拷贝,拷贝构造函数要自己写!!!!
浅拷贝
深拷贝
总结:什么时候用深拷贝什么时候用浅拷贝?编译器自动生成的是深拷贝还是浅拷贝?
就看构造函数中是否动态申请内存空间(new),如果没有就用浅拷贝,如果有就用深拷贝
编译器自动生成的也是浅拷贝
浅拷贝
#include <iostream>
using namespace std;
//封装手机的类
class Phone
{
public:
//构造函数与类同名,无返回值,参数不确定
//默认构造函数
//Phone();
Phone(string brand = "苹果", string color = "粉色", int price = 9999);
void call();
void sendMessage();
void playGames();
void setPrice(int price);
void show();
private:
string brand;
string color;
int price;
protected:
};
//Phone::Phone()
//{
// this->brand = "小米";
// this->color = "白色";
// this->price = 3999;
// cout << "Phone()" << endl;
//}
Phone::Phone(string brand, string color, int price)
{
this->brand = brand;
this->color = color;
this->price = price;
cout << "Phone(string,string,int)" << endl;
}
//返回值的类型 类名::成员
void Phone::call()
{
cout << "打电话" << endl;
}
void Phone::sendMessage()
{
cout << "发短信" << endl;
}
void Phone::playGames()//void Phone::playGames(Phone *const this)
{
cout << "打游戏" << endl;
}
void Phone::setPrice(int price)//void Phone::setPrice(Phone * const this,int
_price)
{
this->price = price;
}
void Phone::show()
{
cout << "品牌:" << this->brand << ","
<< "颜色:" << this->color << ","
<< "价格:" << this->price << endl;
}
int main()
{
//实例化对象 类名 对象名;
Phone phoneA;
phoneA.show();
Phone* p = new Phone("华为");
p->show();
Phone phoneB("oppo", "蓝色");
phoneB.show();
Phone phoneC("苹果", "黑色",2999);
phoneC.show();
delete p;
return 0;
}
深拷贝
#include <iostream>
using namespace std;
//封装手机的类
class Phone
{
public:
//构造函数与类同名,无返回值,参数不确定
//默认构造函数
Phone(string brand = "苹果", string color = "粉色", int price = 9999);
Phone(Phone& demol);
~Phone();
void call();
void sendMessage();
void playGames();
void setPrice(int price);
void show();
private:
string brand;
string color;
int price;
int* p;
protected:
};
Phone::Phone(string brand, string color, int price)
{
this->brand = brand;
this->color = color;
this->price = price;
this->p = new int;
*p = 100;
cout << "Phone(string,string,int)" << endl;
}
Phone::Phone(Phone& demol)
{
cout << "Phone(Phone &)" << endl;
this->brand = demol.brand;
this->color = demol.color;
this->price = demol.price;
this->p = new int;
*(this->p) = *(demol.p);
}
Phone::~Phone()
{
cout << "~Phone()" << endl;
delete p;
cout << this << endl;
}
//返回值的类型 类名::成员
void Phone::call()
{
cout << "打电话" << endl;
}
void Phone::sendMessage()
{
cout << "发短信" << endl;
}
void Phone::playGames()//void Phone::playGames(Phone *const this)
{
cout << "打游戏" << endl;
}
void Phone::setPrice(int price)//void Phone::setPrice(Phone * const this,int
_price)
{
this->price = price;
}
void Phone::show()
{
cout << "品牌:" << this->brand << ","
<< "颜色:" << this->color << ","
<< "价格:" << this->price << endl;
}
int main()
{
Phone phoneA;
Phone phoneB = phoneA;
return 0;
}
析构函数
作用:在对象生命周期结束的时候,回收资源
什么时候调用:对象生命周期结束的时候
谁调用:系统自动调用
如果没有自定义析构函数,系统会自动生成一个空的析构函数
如果自定义了析构函数,系统就会调用自定义的析构函数
析构函数的格式:没有返回值,函数名与类同名,在函数名前加一个~,没有参数(不能重载)
~类名()
{
;
}