一、类和对象的定义
C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++
的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,它包含了数据表示法和用
于处理数据的方法。类中的数据和方法称为类的成员。函数在一个类中被称为类的成员。
打个比方说明一下什么是类,比如有一条小狗,小狗有名字叫旺财,旺财的年龄是 2 岁,
同时旺财会汪汪的叫,也能跑。我们统称狗这个为类,类是我们抽象出来的,因为狗不只有上
面的属性,还有体重,毛发的颜色等等,我们只抽象出几种属性成一个类。具体到哪条狗就叫
对象。
从类中实例化对象分两种方法,一种是从栈中实例化对象,一种是从堆中实例化对象。
类是创建对象的模板,一个类可以创建多个对象,每个对象都是类类型的一个变量;创建对象的过程也叫做类的实例化。
类的定义
class 类名{
public:
公有的数据;
protected:
保护的数据;
private:
私有的数据;};
C++通过 public、protected、private 三个关键字来控制成员变量和成员函数的访问权限,它们分别表示公有的、受保护的、私有的,被称为成员访问限定符。所谓访问权限,就是你能不能使用该类中的成员。
#include <iostream>
using namespace std;
class Dog
{
public://不写关键字的时候默认是private属性
string name;
int age;
void run()
{
cout<<"狗会跑"<<endl;
}
private:
double weight;
};
int main()
{
//从栈中实例化对象
Dog dog1;
dog1.name = "旺财";
cout<<dog1.name<<endl;
dog1.run();
//dog1.weight = 50.2;
//private和protect下面的成员类的对象无法访问
//从堆中实例化对象,要用delete删除
//不用delete删除的话,程序结束后系统会回收
//不删除对象的话,这个指针会占这内存不放,会造成内存泄漏
Dog* dog2 = new Dog;
dog2->age = 3;
cout<<dog2->age<<endl;
delete dog2;
return 0;
}
/* 输出:
旺财
狗会跑
3
*/
二、构造函数和析构函数
定义了一个名称和类名相同,没有返回值的函数,这个函数称为构造函数。构造函数的特殊之处在于,它会在类实例化的时候被调用。
#include <iostream>
class Dog
{
public:
Dog();
};
对象实例化的时候,会调用构造函数,而对象销毁的时候,就会调用析构函数。
对象销毁:程序结束了由系统释放;删除指针对象的时候
#include <iostream>
class Dog
{
public:
~Dog();
};
举个栗子1:
#include <iostream>
using namespace std;
class Dog
{
public:
Dog(){
cout<<"构造函数被执行了"<<endl;
}
~Dog();
};
Dog::~Dog()
{
cout<<"析构函数被执行了"<<endl;
}
int main()
{
Dog dog1;
return 0;
}
举个栗子2:
#include <iostream>
using namespace std;
class Dog
{
public:
Dog(){
cout<<"构造函数被执行了"<<endl;
}
~Dog();
};
Dog::~Dog()
{
cout<<"析构函数被执行了"<<endl;
}
int main()
{
//Dog dog1;
Dog*dog2 =new Dog;
return 0;
}
栗子1输出: 栗子2输出:
构造函数被执行了 构造函数被执行了
析构函数被执行了栗子1是从栈中实例化对象,程序结束了系统会回收对象
栗子2中析构函数没有执行,因为堆中实例化对象要用delete删除,栗子2中的对象没有被销毁
在类实例化对象的时候,如果没有定义构造函数,则编译器会合成一个默认的构造函数;当有了对象后,如果没有定义析构函数,则编译器会合成一个默认的析构函数。
三、this指针
this指针装着当前对象的地址,即每个对象都有自己的地址,我们可通过&t1,&t2...(对对象取地址)获取到各个对象的地址,C++在类内直接提供了地址,我们就不需要在类外获取了。C++面向对象编程提供了一个变量叫做this指针,该地址自动初始化成我们当前对象的地址,我们可以在类内直接使用this指针,就可使用当前对象的地址了。
这时候我们会想到,我直接取对象的地址,通过函数传递到类的内部去使用,为什么还存在this指针呢?这就是C++面向对象编程的思想了,对象表面是个变量,实际上它是区别于变量int、double等等,对象是拥有一个丰富功能的一个完整个体,一个对象自身就知道自己的地址,不需要“别人告诉”。
每个成员函数:析构、构造、自定义函数,都可以使用this指针,this指针作为函数的隐藏参数,传递给函数,每个成员都有,this的实现方法暂不研究。
this指针可用于区分类成员和局部变量
#include <iostream>
using namespace std;
class Test
{
private:
//Test*this; "相当于类"内有this变量
int a;
public:
Test(/* Test*this ,*/int a)
{
this->a = a; //用处1:区分 类成员和函数参数的局部变量
}
void Print(){
cout<<a<<' '<<this<<endl;
}
};
int main()
{
Test t(12);
t.Print();
cout<<"&t:"<<&t<<endl;
return 0;
/*
输出:
12 0x7fff76e94494
&t:0x7fff76e94494
*/
}
this指针可用于以下栗子:
#include <iostream>
using namespace std;
class Test
{
private:
//Test*this; "相当于类"内有this变量
int a;
public:
Test(/* Test*this ,*/int a)
{
//this->a = a; //用处1:区分 类成员和函数参数的局部变量
(*this).a = a;
}
void Print(){
cout<<a<<' '<<this<<endl;
}
Test*GetAddr(){
return this; //用处3:返回当前对象的地址,外部使用
}
Test& GetObject()
{
return *this; //用处4:this是对象的地址,*this是对象本身
}
};
int main()
{
Test t(120);
cout<<t.GetAddr()<<endl;//&t
t.GetObject().Print() ;
return 0;
/*
输出:
ff2b1a2d14
120 0x7fff2b1a2d14
*/
}
四、类的继承
创建新类时,并不需要创建全新的数据和成员函数,我们可以指明这个新类继承现有类的成员。此时,现有的类称为“基类”,继承实现的新类称为“派生类”。
举个栗子:子类可以调用父类的成员
#include <iostream>
using namespace std;
//基类/父类
class Animal
{
public:
string name;
int age;
void run()
{
cout<<"狗的年龄: "<<age<<endl;
}
};
//派生类/子类
class Dog:public Animal
{
};
int main()
{
Dog dog1;
dog1.age = 5;
dog1.run();
return 0;
}
(2)保护继承时基类中各成员属性均变为protected,并且基类中private成员被隐藏。派生类的成员只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象不能访问基类中的任何的成员。
(3)私有继承时基类中各成员属性均变为private,并且基类中private成员被隐藏。派生类的成员也只能访问基类中的public/protected成员,而不能访问private成员;派生类的对象不能访问基类中的任何的成员。
五、函数重载
在同一个作用域内,声明几个功能类似的同名函数,并且这些同名函数的参数个数、参数类型或者参数顺序不同,那么就叫函数重载。
栗子1:
#include <iostream>
using namespace std;
class Dog
{
public:
Dog(int weight)//构造函数重载
{
cout<<"int 狗的体重:"<<weight<<endl;
}
Dog(double weight)//构造函数重载
{
cout<<"double 狗的体重:"<<weight<<endl;
}
};
int main()
{
Dog dog1(50);
Dog dog2(50.5)
return 0;
}
/* 输出:
int 狗的体重:50
double 狗的体重:50.5
*/
栗子2:
#include <iostream>
using namespace std;
class Dog{
public:
void getWeight(int weight){
cout<<"int 狗的体重:"<<weight<<endl;
}
void getWeight(double weight){
cout<<"double狗的体重:"<<weight<<endl;
}
};
int main()
{
Dog dog1;
dog1.getWeight(100);
dog1.getWeight(100.7);
return 0;
}
学习更新行中·········