基本知识
面向对象的编程:
1、自己创建类
2、自己创建对象
- 类的形式:
class student
{
srting name;
int age;
}
- 公有、私有
- 私有的函数需要借用公有的方法调用
class student
{
public://外部可读写
srting name;
private://外部看不到 外部不可读写
int age;
}
- 使用一个类:
student Jane;//创建一个 student 类的对象 名字将Jane Jane.name = “xiaohua”;//赋值
- 什么是成员函数
不同的函数可以使用一样的名字,但是形成不同
class student
{
public:
srting name;
int age;
bool set (int a);
bool set (srting a);//两函数形参不同
}
//成员函数的定义:
bool set (srting a)
{
name = a;
return true;
}
bool set (int a)
{
age = a;
return true;
}
构造函数
不带参数的构造函数
class student
{
public:
srting name;
int age;
student();//这就是构造函数,没有形参,没有返回值,并且名字和类的名字一致
}
student::student()//构造函数定义,冒号两边一样,没有输入值
{
age = 20;//构造函数里面,可以对全部的成员变量一个默认值
name = "xiaohua";
}
以后我再主函数定义新的变量时,变量就会有一个默认值,就是构造函数里面定义的
带参数的构造函数
class student
{
public:
srting name;
int age;
student();//这就是构造函数,没有形参,没有返回值,并且名字和类的名字一致
student(int a, string b);//带参数的构造函数,还是保存和类一样的名字,根据不同的参数进行区别
}
student::student()//构造函数定义,冒号两边一样,没有输入值
{
age = 20;//构造函数里面,可以对全部的成员变量一个默认值
name = "xiaohua";
}
student::student(int a, string b)//构造函数定义,冒号两边一样
{
age = a;//构造函数里面,将输入的值赋值给对象
name = b;
}
int main()
{
student aa;//没有带参数的构造函数默认赋值
student bb(23,"小白");//在定义对象时赋值
return 0;
}
析构函数
student *p = new student(88,"愚公");//创建一个指针p,指向一个新的对象
delete p;//删除指针
//析构函数,执行删除指针时会调用
student :: ~student ()
{
cout<<"delete object";
}
常成员函数const
- 一个方法只读取属性,而不修改属性,就是常成员函数
class student
{
public:
srting name;
int age;
bool set (int i);//普通成员函数声明,又叫方法
bool read() const;//后面加const,表示这个函数只读不写
}
bool student :: read() const//后面加const,表示这个函数只读不写
{
cout<<name;//打印姓名
cout<<age;//打印年龄
return true;
}
int main()
{
student aa;//创建对象
aa.read();//在创建对象后,调用read方法
return 0;
}
//实现上可以不使用const,普通方法也可以读数据,加const只是为了安全起见,防止意外修改数据。
//更加不正规的做法就是直接读取:aa.age,在正规的程序当中还是会使用const来读取。
静态成员函数
- 静态成员数据 ( static):描述全局,又与具体的对象属性无关的变量
- 读取静态成员数据的方法,叫静态成员函数
class student
{
public:
srting name;
int age;
student();//这就是构造函数,没有形参,没有返回值,并且名字和类的名字一致
static int cnt://static 表示静态成员数据,统计有多少个对象
static int count()://static 表示静态成员函数,返回有多少个对象
}
student::student()//构造函数定义,冒号两边一样,没有输入值
{
age = 20;//构造函数里面,可以对全部的成员变量一个默认值
name = "xiaohua";
cnt = cnt + 1;
}
int student ::count()
{
return cnt;//返回静态成员数据,统计有多少个对象
}
int main()
{
student aa;//创建对象
student bb;//创建对象
aa.count();//bb.count();//student ::count();不依赖对象的静态函数
return 0;
}
正规写法
class student
{
public:
bool set (int i);//普通成员函数声明,又叫方法
bool read() const;//后面加const,表示这个函数只读不写
private:
srting name;
int age;
}
- 一般把方法全部放到public中
- “属性”放在privatezho
- 目的是防止类的外部随意篡改数据
- 通过函数来修改数据时,一般都具有防错机制,满足条件才能修改
派生继承
class student
{
public:
bool set (int i);//普通成员函数声明,又叫方法
bool read() const;//后面加const,表示这个函数只读不写
private:
srting name;
int age;
}
class undergraduate : public student //本科生类定义,冒号后面表示从student 类公有派生而来
{
public:
srting course;//这个行新增定义一个公开的字符串属性 course,比如本科生的课程大学物理
}
class postgraduste : public student //研究生类定义,冒号后面表示从student 类公有派生而来
{
public:
srting research;//这个行新增定义一个公开的字符串属性 research,比如研究生的研究方向:芯片设计
}
int main()
{
undergraduate aa;//创建本科生对象
postgraduste bb;//创建研究生对象
aa.set(33);//子类可以调用父类的方法
return 0;
}
- 将student 当中的private变为protect,研究生类就可以继承student 的protect下的内容,而且对应student 来说,protect下的内容和private下的是一样的
> class undergraduate : private student//私有继承,继承所得的public下的内容变为private 下的,不继承private 下的内容
> class undergraduate : protect student//保护继承,继承所得的public下的内容和protect 下的内容都为protect 下的内容
- 子类只能调用父类的构造函数
子类的构造函数
class undergraduate : public student //本科生类定义,冒号后面表示从student 类公有派生而来
{
public:
srting course;//这个行新增定义一个公开的字符串属性 course,比如本科生的课程大学物理
undergraduate();//
undergraduate(int a,string b,string c);//
}
undergraduate :: undergraduate()
{
course = "math"
}
//带参数的构造函数
undergraduate :: undergraduate(int a,string b,string c):st`在这里插入代码片`udent (a,b)
{
course = c;
}
int main()
{
undergraduate aa;//创建本科生对象
postgraduste bb(22,"xiaohua","math");//创建对象,并且赋初值
aa.set(33);//子类可以调用父类的方法
return 0;
}
多态
- 重载:同名的方法,根据不同形参,执行不同的方法
- 隐藏:父类当中定义一个方法,子类可以重新定义,重新定义的方法输入格式相同或者不同都可以
class student
{
public:
bool set (int i);//普通成员函数声明,又叫方法
bool read() const;//后面加const,表示这个函数只读不写
void study(bool a);
private:
srting name;
int age;
}
void student :: study(bool a)
{
cout<<"好好睡觉"
}
class undergraduate : public student //本科生类定义,冒号后面表示从student 类公有派生而来
{
public:
srting course;//这个行新增定义一个公开的字符串属性 course,比如本科生的课程大学物理
void study(bool a);
}
void undergraduate :: study(int a)
{
cout<<"好好吃饭"
}
int main()
{
student aa;//创建父对象
postgraduste bb;//创建子对象
bb。study(2);//打印好好吃饭
aa.study(ture);//打印好好睡觉
bb。study(ture);//报错,父类方法被隐藏了
return 0;
}
-
指针
-
- 父类的指针可以指向子类,子类的指针不可以指向父类
-
- 指向子类的父类指针也只能调用父类的方法和属性,不能调用子类的方法和属性
-
虚函数(virtual)
class student
{
public:
bool set (int i);//普通成员函数声明,又叫方法
bool read() const;//后面加const,表示这个函数只读不写
virtual void study();
private:
srting name;
int age;
}
void student :: study()
{
cout<<"好好学习"
}
class undergraduate : public student //本科生类定义,冒号后面表示从student 类公有派生而来
{
public:
srting course;//这个行新增定义一个公开的字符串属性 course,比如本科生的课程大学物理
virtual void study();
}
void undergraduate :: study()
{
cout<<"好好吃饭"
}
class postgraduste : public student //研究生类定义,冒号后面表示从student 类公有派生而来
{
public:
srting research;//这个行新增定义一个公开的字符串属性 research,比如研究生的研究方向:芯片设计
virtual void study();
}
void postgraduste :: study()
{
cout<<"开开心心"
}
int main()
{
student aa;//创建父对象
postgraduste bb;//创建子对象
undergraduate cc;//创建子对象
student *p;
p = &aa,
p->study();//打印好好学习
p = &bb,
p->study();//打印开开心心
p = &cc,
p->study();//打印好好吃饭
return 0;
}
纯虚函数与抽象函数
class student
{
public:
student ();//抽象类也有构造函数
student (int a,string b);//构造函数重载
virtual void study() =0;//声明方法,前面有virtual还有=0,表示纯虚函数,只有声明没有定义
}
int main()
{
student aa;// 报错 不允许创建对象
postgraduste bb;//创建子对象
undergraduate cc;//创建子对象
student *p;
p = &bb,
p->study();//打印开开心心
p = &cc,
p->study();//打印好好吃饭
return 0;
}
回调实例展示
#include <iostream>
#include <map>
#include <string>
#include "stdio.h"
using namespace std;
class student {
public:
string name;
int age;
~student();
student(); // 这就是构造函数,没有形参,没有返回值,并且名字和类的名字一致
student(
int a,
string
b); // 带参数的构造函数,还是保存和类一样的名字,根据不同的参数进行区别
bool set(int a);
bool set(string a); // 两函数形参不同
bool read() const; // 后面加const,表示这个函数只读不写
static void stuone(int i) {
std::cout << "I an first student" << std::endl; // 打印姓名
std::cout << i << std::endl; // 打印姓名
}
void FunB1(void (*callback)()) {
printf("I'am ProgramB.FunB1() and be called..\n");
callback();
}
};
// 成员函数的定义:
bool student::set(string a) {
name = a;
return true;
}
bool student::set(int a) {
age = a;
return true;
}
student::student() // 构造函数定义,冒号两边一样,没有输入值
{
age = 20; // 构造函数里面,可以对全部的成员变量一个默认值
name = "xiaohua";
}
student::student(int a, string b) // 构造函数定义,冒号两边一样
{
age = a; // 构造函数里面,将输入的值赋值给对象
name = b;
}
// 析构函数,执行删除指针时会调用
student ::~student() { std::cout << "delete object" << std::endl; }
bool student ::read() const // 后面加const,表示这个函数只读不写
{
std::cout << name << std::endl; // 打印姓名
std::cout << age << std::endl; // 打印年龄
return true;
}
typedef void (*FuncPtr1)(int);
std::map<std::string, FuncPtr1> g_TmpCmdMap;
std::map<std::string, int> g_Tmpage;
// 回调函数的注册函数
int registfun(int age, string name, void (*FuncPtr1)(int)) {
student aa; // 创建对象
aa.set(age);
aa.set(name);
aa.read(); // 在创建对象后,调用read方法
g_Tmpage[name] = age;
g_TmpCmdMap[name] = FuncPtr1;
// aa.FunB1(FuncPtr1);
return 0;
}
int checkoutfun(string name) {
std::map<std::string, FuncPtr1>::iterator g_TmpCmdMap1;
std::map<std::string, int>::iterator g_Tmpage1;
g_TmpCmdMap1 = g_TmpCmdMap.find(name);
if (g_TmpCmdMap1 == g_TmpCmdMap.end()) {
printf("%s %d 11111111111111111111\n", __func__, __LINE__);
return 0;
}
g_Tmpage1 = g_Tmpage.find(name);
if (g_Tmpage1 == g_Tmpage.end()) {
printf("%s %d 222222222222222222\n", __func__, __LINE__);
return 0;
}
printf("%s %d 33333333333333333\n", __func__, __LINE__);
g_TmpCmdMap[name](g_Tmpage[name]);
return 0;
}
int main(int argc, char *argv[]) {
printf("%s %d \n", __func__, __LINE__);
registfun(181, "hhh1", student ::stuone);
registfun(182, "hhh2", student ::stuone);
registfun(183, "hhh3", student ::stuone);
registfun(184, "hhh4", student ::stuone);
registfun(185, "hhh5", student ::stuone);
registfun(186, "hhh6", student ::stuone);
registfun(187, "hhh7", student ::stuone);
printf("%s %d ============================ \n", __func__, __LINE__);
checkoutfun("hhh2");
checkoutfun("hhh99");
return 0;
}