C++面向对象但不纯面向对象。JAVA纯面向对象。
所以C++支持C和C++面向对象混编。
C面向过程,关注的是过程
类和结构体的区别:
//C++兼容C结构体的用法。
typedef struct ListNode
{
int val;
struct ListNode* next;
}LTN;
C++
//C++把结构体升级成类
struct ListNode//声明这是个类,struct关键字不能去掉
{
int val;
ListNode* next;//后面想用这个类型的时候可以去掉。
};
如何用类?
C数据和方法分离,C++方法可以在类的里面
struct Stack
{
//成员函数
//成员函数直接定义到类里面
void Init(int n=4)//缺省值
{
a = (int*)malloc(sizeof(int) * n);
if (nullptr == a)
{
perror("malloc申请空间失败");
return;
}
capacity = n;
size = 0;
}
void Push(int x)
{
//...
a[size++] = x;
}
//成员变量
int* a;
int size;
int capacity;
};
int main()
{
Stack st;//对象
//如何调用函数?
st.Init(4);
st.Push(1);
st.Push(2);
st.Push(3);
st.Push(4);
return 0;
}
C++可以用struct定义类,但更喜欢用class定义类。
class className
{
//类体:包括成员函数(类的方法)和成员变量(类的属性)
};//一定要注意后面的分号!!!!
#pragma once
#include
#include
//类成员函数声明和定义分离
struct Stack
{
//成员函数
void Init(int n = 4);//缺省参数在声明给
void Push(int x);//类的声明
//成员变量
int* a;
int size;
int capacity;
};
Stack.cpp
#include "Stack.h"
void Stack::Init(int n)//Stack告诉编译器Init不是全局函数,是栈这个类的成员函数
{
a = (int*)malloc(sizeof(int) * n);//看栈这个类里有没有a这个成员变量
if (nullptr == a)
{
perror("malloc申请空间失败");
return;
}
capacity = n;
size = 0;
}
void Stack::Push(int x)
{
//...
a[size++] = x;
}
用class Stack却编不过,为什么呢?
此时要用到访问限定符。
C++访问限定符有三种:公有保护和私有,现阶段保护和私有没有区别。共有及在类外可以直接访问。保护和私有在类里可以访问,类外不可访问。
公有 | 保护 | 私有 |
---|---|---|
public | protect | private |
#pragma once
#include
#include
struct Stack
{
public:
void Init(int n = 4);
void Push(int x);
private:
int* a;
int size;
int capacity;
};
大多数情况下成员变量都是私有的,成员函数不给别人用的是私有,给别人用的是公有。
C++中struct和class没有区别,但是struct可以像C语言去用。
Test.cpp
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Stack st;
Date d1;
d1.Init(2023, 2, 3);//调用函数,年月日被初始化
return 0;
}
【面试题】:面向对象的三大特性:封装,继承,多态
封装:将下面的细节藏起来,本质是一种更好的管理。
C++的封装:将数据和方法都放在类里面去了,即当前封装的极限,并把自己想访问的定义成共有,不想的定义成私有和保护。
类定义出一个新的作用域(类域)。
class Person
{
public:
void PrintPersonInfo();
private:
char _name[20];
char _gender[3];
int _age;
};
void Person::PrintPersonInfo()//PrintPersonInfo属于Person这个类域
{
cout<<_name<<" "<<_gender<<" "<<_age<<endl;//此时可以调用私有
}
即用类类型
声明即要定义这个函数或变量,这个变量的类型是什么,名称是什么,参数是什么,但实际这个变量没有出来。定义即把其实实在在在的空间给开出来(对于变量而言)。
类就像一个别墅的设计图,设计了细节,但不能住人,实例化即根据设计图建造出一栋栋别墅。
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}//函数的定义
private:
int _year;
int _month;
int _day;//声明,没有开空间
};
只需要计算成员变量的大小。
int main()
{
//类对象实例化--开空间
Date d1;//定义才是开空间,对于对象整体定义。
//Date._year=1;
//Date::year=0;
//以上两种不可以,声明内不可存数据。
//d1._year=1;//也不行,访问限定符是私有的。访问不了,访问的时候需要调用这个函数。改成公有就可以了。
d1.Init(2023,9,12);//Init函数存在哪里呢?
d1._year++;
cout<<sizeof(d1)<<endl;
//类对象大小要考虑内存对齐规则
return 0;
}//输出12
为什么成员变量存在对象里面,成员函数不存在对象里面?
每个对象的成员变量不一样,需要独立存储。
每个对象调用的成员函数一样,放到共享公共区域(代码段)。
只需要计算成员变量的大小。
//类中既有成员变量,又有成员函数
class A1{
pubic:
void f1(){}
private:
int a;
};//sizeof(A1):4
//类中仅有成员函数
class A2{
public:
void f2(){}
};//sizeof(A2):1//【考点】如果是0,A2 aa1;没有实例化,不能取地址
//类中什么也没有
class A3
{};//sizeof(A3):1,这一个字节用来进行占位,不存储有效数据,标识对象存在过,被实例化定义出来了。
没有成员变量的类都是一个字节
原来代码:
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
编译器处理完:
class Date
{
public:
void Init(Date*this,int year, int month, int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
原来代码:
int main()
{
Date d1;
Date d2;
d1.Init(2023, 2, 3);
d2.Init(2022, 2, 3);
return 0;
}
编译器处理完:
int main()
{
Date d1;
Date d2;
d1.Init(&d1,2023, 2, 3);
d2.Init(&d2,2022, 2, 3);
return 0;
}
如果是d1调用,this是d1的地址,赋值给d1的年月日。
不可以自己去加。
//可以在类里使用this,但是实参和形参里不可以
cout<<this<<endl;
this->_year = year;
this->_month = month;
this->_day = day;
//一般不会这么写
void func()
{
cout<<this<<endl;
cou<<"func()"<<endl;
}
int main()
{
//编译报错 运行崩溃 正常运行
Date* ptr=nullptr;
ptr->func();
//结果:正常运行
ptr->Init(2023,9,12);//运行崩溃,用this去解引用了this->year
ptr->_year;//会崩溃,因为_year在对象里面,到指针指向的对象去找,指针是一个空指针,相当于解引用。
(*ptr).func();//正常运行,ptr真正的意义是传递给this,所以也是正常运行,没有解引用这个行为
Date::func();//不能这么调用,因为要传递this指针。没有this指针调用。
}
指针调用用箭头,有箭头不一定解引用。函数不在对象里。调用这个函数要call这个地址,这个地址在公共区域去找,公共区域:代码段。
成员函数不可以不用对象去调,直接func()。
C语言和C++真正的区别:数据结构的实现与语言无关
C | C++ | |
---|---|---|
数据和方法 | 分离的 | 都封装在类里面 |
名字 | 繁琐 | 简洁 |
数据访问 | 自由不受限制 | 控制访问方式。愿意给你访问的公有,不愿意私有 |
底层 | 一样 |
封装在一起才能通过访问限定符限制。