一、类、对象
1.介绍
类(class)是一个模型(就像是一张蓝图,它决定一个对象将拥有什么样的属性、功能等),且每个类跟变量一样都有一个名字。当我们为这个类创建实例的时候,也就是对象(类的具体化实现)。
类由变量(类里的变量称属性)和函数(类里的函数称方法)组成,对象将使用那些变量来存放信息,调用那些函数来完成操作。同理对象内部有变量和函数,而结构通常只由各种变量构成。
2.示例
/*
对象应用--造一辆车
*/
#include<iostream>
#include<string>
using namespace std;
const int FULL_GAS = 85;//宏定义
class Car
{
public:
string color;//变量(属性)
string engine;
unsigned int gas_tank;
unsigned int wheel;
void setColor(string clo);//函数(方法)
void setEngine(string eng);
void setWheel(unsigned int whe);
void fillTank(int liter);
int running(void);
void warnning(void);
};
void Car::setColor(string clo)
{
color = clo;
}
void Car::setEngine(string eng)//函数的定义
{
engine = eng;
}
void Car::setWheel(unsigned int whe)
{
wheel = whe;
}
void Car::fillTank(int liter)
{
gas_tank = liter;
}
int Car::running(void)
{
cout << "我正在往前移动……超过山丘" << endl;
gas_tank -- ;
cout << "当前还剩" << 100 * gas_tank / FULL_GAS << "%" << "油量";
return gas_tank;
}
void Car::warnning(void)
{
cout << "WARNNING!!!" << "还剩" << 100 * gas_tank / FULL_GAS << "%" << "油量";
}
int main()
{
char i;
Car mycar;
mycar.setColor("red");
mycar.setEngine("V8");
mycar.setWheel(4);
mycar.gas_tank = FULL_GAS;
while (mycar.running())
{
if (mycar.gas_tank < 10)
{
mycar.warnning();
cout << "请问是否需要加至满油?" << endl;
cin >> i;
if (i == 'Y' || i == 'y')
{
mycar.fillTank(FULL_GAS);
}
}
}
return 0;
}
二、构造器与析构器
1.介绍
(1)构造器
构造器(Constructor)是用于初始化对象的一种特殊成员函数,当对象(类的实例)创建时,将自动调用构造函数,以确保对象在创建时具有正确的初始状态。它是该类的特殊成员函数。
①构造器的名字必须和它所在的类的名字相同;
②创建对象时会自动调用构造函数;
③构造器永远不会返回任何值;
④如果我们没有指定构造函数,C ++编译器会生成一个默认构造函数(不需要参数并且有一个空体)。
(2)析构器
构造器用来完成事先的初始化和准备工作(申请分配内存),析构器用来完成事后所必须的清理工作(清理内存)
析构器和构造器有着一样的名字,只是前边多了一个波浪符"~"前缀。
①析构器永远不返回任何值
②析构器不带参数
③在复杂的类里,析构器往往十分重要(可能会引起内存的泄露)
class Car
{
Car(void);
~Car();
}
2.示例
/*
构造器与析构器
*/
#include<iostream>
#include<string>
using namespace std;
class BaseClass
{
public:
BaseClass();
~BaseClass();
void doSomething();
};
class SubClass:public BaseClass
{
public:
SubClass();
~SubClass();
};
BaseClass::BaseClass()
{
cout << "进入dad构造器" << endl;
}
BaseClass::~BaseClass()
{
cout << "进入dad析构器" << endl;
}
SubClass::SubClass()
{
cout << "进入son构造器" << endl;
}
SubClass::~SubClass()
{
cout << "进入son析构器" << endl;
}
void BaseClass::doSomething()
{
cout << "doing something..." << endl;
}
int main()
{
SubClass son;
son.doSomething();
cout << "收工!" << endl;
return 0;
}
运行结果:
三、覆盖
1.介绍
当我们需要在基类里提供一个通用的函数,但在它的某个子类里需要修改这个方法的实现,覆盖(overriding)就可以做到。
补充知识:访问级别
public | 任何代码 |
protected | 这个类和它的子类 |
private | 只有这个类本身 |
2.示例
/*
学习目标:覆盖
程序功能:为 Animal 添加 eat()方法,并在 Pig 中覆盖
*/
#include<iostream>
#include<string>
using namespace std;
class Animal
{
public:
string mouth;
Animal(string theName);
void eat();
protected:
string name;
};
class Pig:public Animal
{
public:
Pig(string theName);
void eat();//
};
Animal::Animal(string theName)//基类构造器,注意main()里的新对象的定义
{
name = theName;
}
void Animal::eat()//old
{
cout << "I'm eating..." << endl;
}
Pig::Pig(string theName) :Animal(theName)//子类构造器注明继承于父类
{
//继承基类的构造函数,这里啥也不写
}
void Pig::eat()//new,overriding!
{
cout << "Eating meat..." << endl;
}
int main()
{
Pig pig("小猪");//定义一个对象pig,由于其继承于类Animal,
//且构造函数也继承于类Animal的构造函数,
//所以参数"小猪"将赋值给类Pig中的名字属性name
pig.eat();
return 0;
}
运行结果:
可以看到“Eating meat...”覆盖了“I'm eating...”
四、重载
1.介绍
重载机制可以定义多个同名的方法(函数),只是它们的输入参数必须不同。(因为编译器是依靠不同的输入参数来区分不同的方法)
重载相较于覆盖,声明的输入参数或返回值与原来的不一致。
2.示例
/*
学习目标:重载
程序功能:调用Pig中两个同名函数eat()与eat(int eatCount)
*/
#include<iostream>
#include<string>
using namespace std;
class Animal
{
public:
string mouth;
Animal(string theName);
void eat();
void eat(int eatCount);
protected:
string name;
};
class Pig:public Animal
{
public:
Pig(string theName);
};
Animal::Animal(string theName)//基类构造器,注意main()里的新对象的定义
{
name = theName;
}
void Animal::eat()//不带参
{
cout << "I'm eating..." << endl;
}
void Animal::eat(int eatCount)//带参
{
cout << "I've eaten " << eatCount << " apples." << endl;
}
Pig::Pig(string theName) :Animal(theName)//子类构造器注明继承于父类
{
//继承基类的构造函数,这里啥也不写
}
int main()
{
Pig pig("小猪");//定义一个对象pig,由于其继承于类Animal,
//且构造函数也继承于类Animal的构造函数,
//所以参数"小猪"将赋值给类Pig中的名字属性name
pig.eat();
pig.eat(5);
return 0;
}
运行结果:
五、友元函数
1.介绍
定义: 友元关系是类之间的一种特殊关系,这种关系不仅允许友元类访问对方的 public 方法和属性,还允许友元访问对方的 protected 和 private 方法和属性。
声明方式: 声明一个友元关系的语法很简单,只要在类声明里的某个地方加上一条 friends class ** 就行了。 这条语句可以放在任何地方,放在 public,protected,private 段落里都可 以。
2.示例
/*
学习目标:友元函数
程序功能:1.Lovers 类有两个子类:分别为 Boyfriend 类和 Girlfriend 类;
2.Lovers 类的方法有 kiss();
3.另增加第三类 Others 类作为路人甲的代表;
4.Others 类调用 kiss()方法
*/
#include<iostream>
#include<string>
using namespace std;
class Lovers
{
public:
Lovers(string theName);//构造器
void kiss(Lovers *lover);
protected:
string name;
friend class Others;//友元关系,可以访问name
};
class Girlfriend:public Lovers//子类
{
public:
Girlfriend(string theName);
};
class Boyfriend :public Lovers//子类
{
public:
Boyfriend(string theName);
};
class Others//友元类
{
public:
Others(string theName);
void kiss(Lovers* lover);
protected:
string name;
};
Lovers::Lovers(string theName)
{
name = theName;
}
void Lovers::kiss(Lovers* lover)//lover是指针
{
cout << "normal:kiss" << lover->name << "10次" << endl;
}
Girlfriend::Girlfriend(string theName):Lovers(theName)//构造器继承
{
}
Boyfriend::Boyfriend(string theName) : Lovers(theName)
{
}
Others::Others(string theName)
{
name = theName;
}
void Others::kiss(Lovers* lover)
{
cout << "kiss" << lover->name << "1次" << endl;
}
int main()
{
Girlfriend girlfriend("小红");
Boyfriend boyfriend("小明");
Others others("路人甲");
girlfriend.kiss(&boyfriend);
cout << "路人甲出现..." << endl;
others.kiss(&girlfriend);
return 0;
}