1.面向对象
1.1 先介绍类和对象:
类:从一些相似的事物中抽离出来一些相同的属性(数据)和行为(函数),抽象成一个类。
对象:类里面具体的某一个事物,比如:图书——c语言,角色里面——吕布,武器——方天画戟
对象:从特定的类别中创造出一个具体的事物。
1.2 C++面向对象解决问题的思路:
1.设计类
2.创建对象
3.使用对象去解决问题
1.3 C++里面4大特征:
1、抽象:从一些相似的实物中抽离出来一些相同的属性(数据)和行为(函数),抽象成一个类
2、封装:加了权限--基于安全考虑
3、继承:从一个类里面继承另外一个类的一些属性或者行为 动物:年龄、叫 ,狗,猫
4、多态:不同事物对同一行为的不同表现 , 比如:打怪兽 , 怪兽打死、怪物反杀、掉血
2 类设计
一定要抽离出来属性和行为
2.1类定义
格式:
class 类名
{
private:
私有的成员变量和成员变量
protected:
保护的成员变量和成员函数
public:
公共的成员变量和成员函数
};
例子:
狗类:-- 属性 --- 种类、体型、毛色、年龄
-- 行为 --- 叫 -- 函数
class Dog
{
private:
string brand;
string size;
string color;
int age;
public:
void bark(void)
{
cout <<"汪汪汪"<<endl;
}
};
数据类型:Dog
Dog d;
d.bark();
2.2 权限
public:所有的成员属性和成员函数可以在类内访问,也可以在外部通过创建对象进行调用
private:所有的成员属性和成员函数可以在类内访问,不能在外部访问,一般设计接口函数 get set函数
protected:所有的成员属性和成员函数可以在类内访问,也可以在它的子类中访问
举例:public 属性和函数
#include<iostream>
using namespace std;
class Dog
{
public:
string brand;
string size;
string color;
int age;
public:
void bark(void)
{
cout << "汪汪汪" << endl;
}
};
int main()
{
Dog a,b;
a.brand = "拉布拉多";
cout << a.brand << endl;
b.bark();
return 0;
}
举例:public属性和函数
#include<iostream>
using namespace std;
class Dog
{
private:
string brand;
string size;
string color;
int age;
public:
void bark(void)
{
cout << "汪汪汪" << endl;
}
void setBrand(string b)
{
brand = b;
}
string getBrand(void)
{
return brand;
}
};
int main()
{
Dog a;
a.setBrand("xiaohuagou");
cout << a.getBrand() << endl;
return 0;
}
举例:protected属性和成员,设计到继承 -- 继承public和protected成员
#include<iostream>
using namespace std;
class Dog
{
protected:
string brand;
string size;
string color;
int age;
public:
void bark(void)
{
cout << "汪汪汪" << endl;
}
void setBrand(string b)
{
brand = b;
}
string getBrand(void)
{
return brand;
}
};
// 继承
class B:public Dog
{
public:
void test()
{
cout << brand << endl;
}
};
int main()
{
Dog a;
a.setBrand("xiaohuagou");
cout << a.getBrand() << endl;
B t;
t.setBrand("xiaobaicai");
t.test();
return 0;
}
一般设计类的时候属性设计成私有的-private,函数设计成共有的-public。
3.成员函数
3.1 成员函数介绍
分类:普通成员函数、构造函数、析构函数、复制构造函数
定义位置:
类内定义:默认是内联函数
类外定义:类内声明,类外定义——推荐写法
类外定义的函数名前要加 类名::
3.2 this指针
成员函数内部有一个this指针。谁调用成员函数,this指针指向谁。
类里面所有的对象都有独立的属性成员,成员函数是共有的。
this指针是类成员函数内部隐藏存在的。
如果成员的名称和参数的名称重复了,就需要显示使用this指针赋值。
void Point::setX(int xp)
{
// this->xp = xp; // 指针形式
// this指针指向了调用它的对象 ,this指针保存了对象的地址
// *this --- 调用的对象
(*this).xp = xp; // 对象形式
}
3.3特殊函数之普通构造函数
作用:构造函数是在创建对象的时候自动调用,一般完成对象的赋值或者初始化操作。
分类:普通构造函数 复制构造函数
普通构造函数格式
类名(形参)
{
}
tips:1.构造的函数名称一定要和类名一致。
2.不写返回值类型。
3. 创建对象的时候自动调用,不能手动调用。
4. 构造函数写在public权限里面。
5. 函数构造可以有多个,支持函数重载。
6. 构造函数如果定义就用定义的构造函数,如果没有定义就使用系统默认的。
7. 构造函数支持形参默认值,但是形参默认是和函数重载在一起的时候小心冲突。
8. 构造函数写在类外部,有默认参数的时候,默认参数只能有一个位置,定义或者声明,尽量将默认参数写在类内部的函数声明的位置。
例子:
#include<iostream>
using namespace std;
class Point
{
private:
int xp;
int yp;
public:
// Point()
// {
// cout << "无参构造函数执行" << endl;
// }
Point(int x=0,int y=0)
{
xp = x;
yp = y;
cout << "有参构造函数执行" << endl;
}
void show(void)
{
cout << xp << "," << yp << endl;
}
};
int main()
{
Point a(1,3);
a.show();
Point b;
b.show();
Point c(3);
c.show();
return 0;
}
函数声明的时候设置默认参数:
#include<iostream>
using namespace std;
class Point
{
private:
int xp;
int yp;
public:
// Point()
// {
// cout << "无参构造函数执行" << endl;
// }
Point(int x=0,int y=0);
void show(void)
{
cout << xp << "," << yp << endl;
}
};
Point::Point(int x,int y)
{
xp = x;
yp = y;
cout << "有参构造函数执行" << endl;
}
int main()
{
Point a(1,3);
a.show();
Point b;
b.show();
Point c(3);
c.show();
return 0;
}
3.4特殊构造函数之析构函数
析构函数:对象销毁的时候自动调用的函数,一般用来清除数据成员的空间。
格式:
~类名()
{
}
tips:
1、析构函数只能有一个。
2、使用对象超出其作用域 ,自动调用对应的类的析构函数。
3、析构函数是用来清理空间(有堆区空间,则需要清理堆区空间)(不是释放成员空间。)
4、为了安全,防止存在隐患---防止内存泄漏。
5、函数名与类名相同,并且前面加上~。
6、没有返回值类型,没有形参。
7、析构函数可以显式调用,通常不显式调用 -- 不推荐。
8、析构如果自定义就使用定义的析构,如果没有提供那就调用系统提供的析构函数。
例子:
#include<iostream>
using namespace std;
class Point
{
private:
int xp;
int yp;
int *zp;
public:
// 创造对象的时候自动调用
Point(int x,int y)
{
xp = x;
yp = y;
zp = new int;
cout << "调用有参构造函数" << endl;
}
// 对象销毁的自动调用,析构函数
~Point()
{
if(zp != NULL)
{
delete zp;
zp = NULL;
cout << "析构函数" << endl;
}
}
};
int main()
{
Point a(1,3);
a.~Point();
return 0;
}
3.5特殊函数之复制构造函数
作用:对象复制。
默认构造函数,可以实现讲一个对象中的数值一对一的复制到另一个空间里面去
#include<iostream>
using namespace std;
class Point
{
public:
int xp;
int yp;
Point(int x,int y)
{
xp = x;
yp = y;
}
void show(void)
{
cout << "xp:" << xp << ",yp:" << yp << endl;
}
};
int main()
{
Point a(1,3);
Point b = a;
a.show();
b.show();
return 0;
}
但是如果数据成员里面有指针,那就会造成多个对象的成员指向了同一片空间,就可能造成误操作。
解决办法:自定义赋值构造函数。
复数构造函数格式:
类名(const 类名 &形参名)
{
//自己实现对成员数据的——赋值
}
tips:
1.一个类里面复制构造函数只能有一个
2.和类同名,有一个参数,一般是常量引用对象
3.一般复制构造不写,使用默认的,但是如果成员有指针或者堆区空间就要自定义
4.普通构造函数和复制构造函数只会执行一个,具体看参数怎么
例子:
#include<iostream>
using namespace std;
class Point
{
public:
int xp;
int yp;
int *zp;
Point(int x,int y)
{
xp = x;
yp = y;
}
Point(const Point& p1)
{
xp = p1.xp;
yp = p1.yp;
zp = new int;
// 拷贝堆区的值
*zp = *(p1.zp);
cout << "复制构造函数" << endl;
}
void show(void)
{
cout << "xp:" << xp << ",yp:" << yp << ",*zp" << *zp << endl;
}
};
int main()
{
Point a(1,3);
a.zp = new int;
*(a.zp) = 100;
// Point b = a;
Point b(a);
a.show();
b.show();
*(b.zp) = 200;
a.show();
b.show();
return 0;
}
例子:普通构造函数和复制构造函数
#include<iostream>
using namespace std;
class Point
{
public:
int xp;
int yp;
int *zp;
Point(int x,int y)
{
xp = x;
yp = y;
cout << "普通构造函数" << endl;
}
Point(const Point& p1)
{
xp = p1.xp;
yp = p1.yp;
zp = new int;
// 拷贝堆区的值
*zp = *(p1.zp);
cout << "复制构造函数" << endl;
}
void show(void)
{
cout << "xp:" << xp << ",yp:" << yp << ",*zp" << *zp << endl;
}
};
int main()
{
Point a(1,3); // 普通构造函数
Point b(a); // 复制构造函数
return 0;
}
3.6数据成员的初始化
1、初始化表达式 (非静态成员)
类名(形参):成员名(参数名),成员名(参数名)
{
}
tips:
1.初始化表达式放在构造函数。
2.如果成员里面有const成员那么只能通过初始化的形式赋值。
3.如果构造函数重载了,在所有的构造函数后面都要设置初始化表达式。
例子:
#include<iostream>
using namespace std;
class Point
{
public:
int xp;
int yp;
const int zp;
Point(int x,int y,int z):xp(x),yp(y),zp(z)
{
}
Point(int z):zp(z)
{
xp = 5;
yp = 10;
}
void show(void)
{
cout << "xp:" << xp << ",yp:" << yp << ",zp" << zp << endl;
}
};
int main()
{
Point a(1,3,5);
a.show();
Point b(5);
b.show();
return 0;
}
over!over!
今天脑抽啦,感冒发烧了,整个脑袋空空的!
系甘先,拜拜啦!