目录
前言:
c++面向对象有三个特性:分别是封装、继承、多态
❀定义:
❀封装:三大特征之一
封装的意义:
思路示例:
问题:
解决方案:
一点专业术语:
权限:
保护权限和私有权限的区别:
struct和class区别:
将成员属性设置为私有
封装案例:
❀对象特征:
对象的初始化和清理:
why?
如何进行初始化和清理呢?
使用构造函数和析构函数编辑
构造函数语法:
析构函数语法:
构造函数的分类:
两种分类方式:
三种调用方法:
括号法(默认构造函数调用)
显示法
隐式转换法
拷贝调用函数的调用时机
1.使用一个已经常见完毕的对象来初始化一个新对象
2.值传递的方式给函数参数传值。
3.以值方式返回局部对象
构造函数调用时机:
结语:
类和对象在c++中是最重要的一部分内容之一,这里会根据三大特性去讲解类和对象的内容,本文具体先介绍其中一个,认真观看哦(ง •_•)ง
前面传送门:
c++入门学习(一)-CSDN博客
c++入门学习(二)-CSDN博客
万事万物都可称为对象
对象有属性有行为,具有相同性质的对象,抽象后为一个类,比如人类
类里包含对象属性、对象行为,
有三大权限私有权限,公共权限,保护权限
将属性和行为作为一个整体,表现生活中的事物(万事万物对象),并加以权限控制
问题:
写一个圆类,求周长?
解决方案:
公式:2*派*半径
关键字——class
后面紧接着是变量名
访问权限:公共权限
属性:半径
行为:获取圆的周长
通过这个类创造一个具体的圆对象
通过点给圆对象属性进行赋值
⭐类中的属性和成员统一成为成员
⭐属性又称为:成员属性、成员变量
⭐行为又称为:成员函数
public公共权限成员类内可以访问,类外也可以用,
protected保护权限成员类内可以访问,
private私有权限成员类内可以访问
举例:
保护权限,就是父亲的权限,儿子也可以访问,
私有权限,父亲的私人权限不可以被访问,私有的,这些在继承时会具体讲解
这些权限可以在一个类中多次使用,一个类并没有规定必须只能有一个公共权限等权限
如果保护权限和私有权限在类外发生访问,结果会出错
基本相同,但是默认的访问权限不同
struct默认权限公共
class默认权限为私有(默认是类里不写权限默认情况下是私有的)
优点:可以自己控制读写功能、对于自己写的权限可以检测数据有效性
用private?
但是如果想让私有权限里的变量可以控制是“可读可写”/“只写”/“只读(设置传入值不行只能获取)”
只用这个私有权限是无法实现这个效果的,因此需要配合公共权限来实现
示例:
#include
#include
using namespace std;
int main()
{
class student {
public:
void setname(string Name){
name = Name;
}
string getname(){
return name;
}
int getold() {
return old;
}
void setidol(string Idol){
idol = Idol;
}
private:
string name;//设置为可写可读
int old=18;//设置为可读
string idol;//设置为可写不可读
};
student s;
s.setname("何灰灰"); //设置姓名
cout << "姓名: " << s.getname() << endl;//输出
cout << "年龄: " << s.getold() << endl;
s.setidol("何白白");//设置可写,但是不可读出。
system("pause");
return 0;
}
设计立方体并求出体积和面积
代码:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
int main()
{
class cube {
public:
//行为
//设置获取长宽高
void setl(int l) {
m_l = l;
}
int getl() {
return m_l;
}
void seth(int h) {
m_h = h;
}
int geth() {
return m_h;
}
void setw(int w) {
m_w = w;
}
int getw() {
return m_w;
}
//获取面积
int gets() {
int calculates = 2 * m_l * m_w + 2 * m_l * m_h + 2 * m_w * m_h;
return calculates;
}
//获取立方体体积
int getv() {
int calculatev = m_l * m_w *m_h ;
return calculatev;
}
private:
//属性
int m_h;
int m_w;
int m_l;
};
cube c1;
cube c2;
c1.setl(10);
c1.setw(10);
c1.seth(10);
cout << "c1面积为" << c1.gets() << endl;
cout << "c1体积为" << c1.getv() << endl;
system("pause");
return 0;
}
保证数据安全的问题,一个对象或者是变量没有初始化,则后面的后果是未知的,同样,没有清理也是可能会造成一系列的安全问题。
使用构造函数和析构函数
构造函数语法:
类名(){}
1.构造函数,没有返回值也不写void
2.函数名称与类名相同
3.构造函数可以有参数,因此可以发生重载
4.程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次自己不写,程序会自动帮你实现,不过函数里面的代码是空的,要是自己写,程序运行你自己写的构造函数
析构函数语法:
~类名(){}
1.析构函数,没有返回值也不写void
2.函数名称与类名相同,在名称前加上符号
3.析构函数不可以有参数,因此不可以发生重载
4.程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次自己不写,程序会自动帮你实现,不过函数里面的代码是空的,要是自己写,程序运行你自己写的析构函数
代码:
#include
#include using namespace std; class person{ public: //创造构造函数 person() { cout << "构造函数" << endl; } ~person() { cout << "析构函数调用" << endl; } }; void test1() { person a; }//局部变量,在栈区上创建,test执行完毕后,释放对象,会自动实现析构函数,不过是空的 //当自己创建了一个,那么就执行自己创建的析构函数 int main() { test1(); system("pause"); return 0; }
按照参数分类:有参数和无参数(默认情况下为无参)
按照类型分类:普通和拷贝
拷贝:copy、复制,
例如:person(const person &a){name=a.name;};把其他的属性拷贝到这个上面
拷贝方式创建,注意括号里写要copy的对象,并加上const,以引用的方式写入。
三种构造函数的具体表示:
#include
#include using namespace std; class person{ public: //创造构造函数 person() { cout << "默认构造函数" << endl; } person(int age) { cout << "有参构造函数" << endl; Age = age; } person(const person& p) { cout << "拷贝构造函数" << endl; Age = p.Age; } ~person() { cout << "析构函数调用" << endl; } int Age; };
引用:c++引用-CSDN博客
person p1;调用无参构造函数,也是默认构造函数调用;
person p2(12);调用有参构造函数
person p3(p2);调用拷贝构造函数
注意事项:调用默认构造函数的时候不要加(),因为编译器会认为这个是一个函数声明,不会认为在创建对象
person p1;默认构造
person p2=person(12);有参构造
person p3=person(p2);拷贝构造
单独拿出来person(12),称为匿名对象,当前执行结束后,系统会立即回收掉匿名对象,马上析构掉
不单独看这个,匿名对象就有名字了,左边的就是它的名字
注意:不要利用拷贝构造函数初始化匿名对象。编译器会认为person(p3)==person p3;认为这是一个对象声明
person p4=10;相当于写了person p4=person(10)有参构造
person p5=p4;拷贝构造
括号法最简单,这里推荐使用这个
#include
using namespace std;
class person{
public:
//创造构造函数
person() {
cout << "默认构造函数" << endl;
}
person(int age) {
Age = age;
cout << "有参构造函数" << endl;
}
person(const person & a) {
Age = a.Age;
cout << "拷贝构造函数" << endl;
}
~person() {
cout << "析构函数调用" << endl;
}
int Age;
};
void test1() {
person a;//局部变量,在栈区上创建,test执行完毕后,释放对象
}
//使用一个已经创建完毕的对象来初始化一个新的对象
void test2() {
person p(20);//调用有参构造函数
person p1(p);//调用拷贝构造函数
}
int main()
{
//test1();
test2();
system("pause");
return 0;
}
输出结果:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
class person{
public:
//创造构造函数
person() {
cout << "默认构造函数" << endl;
}
person(int age) {
Age = age;
cout << "有参构造函数" << endl;
}
person(const person & a) {
Age = a.Age;
cout << "拷贝构造函数" << endl;
}
~person() {
cout << "析构函数调用" << endl;
}
int Age;
};
//值传递的方式给函数参数传值
void test(person p)
{
}
void test3() {
person p;//调用默认构造函数
test(p);//调用拷贝构造函数,因为这里是以值传入,相当于拷贝一个副本传进去
}
int main()
{
//test1();
//test2();
test3();
return 0;
}
示例:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
class person{
public:
//创造构造函数
person() {
cout << "默认构造函数" << endl;
}
person(int age) {
Age = age;
cout << "有参构造函数" << endl;
}
person(const person & a) {
Age = a.Age;
cout << "拷贝构造函数" << endl;
}
~person() {
cout << "析构函数调用" << endl;
}
int Age;
};
//以值返回局部对象
person test0() {
person p;//局部对象在完成函数之后会被自动释放掉,但是现在以值方式返回,则在返回的时候会自动给创建一个新的对象
cout << "p地址" << (int*) & p << endl;
return p;//返回的是p拷贝的一个新的对象
}
void test4() {
person a=test0();//这里的函数a没有调用析构函数和构造函数
cout << "a地址" << (int*)&a << endl;
}
int main()
{
//test1();
//test2();
//test3();
test4();
system("pause");
return 0;
}
默认情况添加的函数:
⭐注意:拷贝构造函数默认情况下只写值传递语句,不会出现输出语句
构造函数调用规则如下:
若用户定义有参构造函数,c++不再提供默认无参构造,但是会提供默认拷贝构造函数,当仅定义有参构造函数时不要进行默认无参构造,会发生错误显示没有默认无参构造函数。
若用户定义拷贝构造函数,c++不会再次提供其他构造函数
只定义拷贝构造函数时如果使用其他的构造函数,则会发生错误
感谢观看点赞收藏,下个文章会讲解有关深浅拷贝的问题以及继承等c++入门知识。