一、类和对象
面向对象三大特点:封装、继承、多态。
struct 中所有行为和属性都是 public 的(默认)。C++中的 class 可以指定行为和属性的访问方式。
封装,可以达到,对内开放数据,对外屏蔽数据,对外提供接口。达到了信息隐蔽的功能。
class 封装的本质,在于将数据和行为,绑定在一起然后能过对象来完成操作 。
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
struct Hero
{
char name[64];
int sex;
};
void printHero(struct Hero &h)
{
cout << "Hero" << endl;
cout << "name = " << h.name << endl;
cout << "sex = " << h.sex << endl;
}
class AdvHero
{
public://访问控制权限
char name[64];
int sex;
void printHero()
{
cout << "advHero" << endl;
cout << "name = " << name << endl;
cout << "sex = " << sex << endl;
}
};
void test01() {
Hero h;
strcpy(h.name, "gailun");
h.sex = 1;
printHero(h);
AdvHero advH;
strcpy(advH.name, "ChunBro");
advH.sex = 1;
advH.printHero();
}
class Animal
{
//{}以内 叫类的内部, 以外叫类的外部
public:
char kind[64];
char color[64];
//在public下面定义成员变量和函数 是能够在类的内部和外部都可以访问的。
void printAnimal()
{
cout << "kind = " << kind << endl;
cout << "color = " << color << endl;
}
void write()
{
cout << kind << "开始鞋子了" << endl;
}
void run()
{
cout << kind << "跑起来了" << endl;
}
//
private:
//在private下面定义的成员变量和方法只能够在类的内部访问
};
void test02() {
Animal dog;
strcpy(dog.kind, "dog");
strcpy(dog.color, "yellow");
Animal sheep;
strcpy(sheep.kind, "sheep");
strcpy(sheep.color, "white");
dog.write();
sheep.run();
}
int main(void)
{
test01();
cout << "-----------" << endl;
test02();
return 0;
}
#endif
二、类的封装
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
//struct
using namespace std;
struct Date
{
int year;
int month;
int day;
};
void init_date(struct Date & d)
{
cout << "year, month, day" << endl;
cin >> d.year;
cin >> d.month;
cin >> d.day;
}
//打印data的接口
void print_date(struct Date &d)
{
cout << d.year << "年" << d.month << "月" << d.day << "日" << endl;
}
//是不是闰年
bool is_leap_year(struct Date &d)
{
if (((d.year % 4 == 0) && (d.year % 100 != 0)) || (d.year % 400 == 0)) {
return true;
}
return false;
}
void test01() {
Date d1;
init_date(d1);
print_date(d1);
if (is_leap_year(d1) == true) {
cout << "是闰年 " << endl;
}
else {
cout << "不是闰年 " << endl;
}
}
//类
class MyDate
{
public:
//成员方法 成员函数
void init_date()
{
cout << "year, month, day" << endl;
cin >> year;
cin >> month;
cin >> day;
}
//打印data的接口
void print_date()
{
cout << year << "年" << month << "月" << day << "日" << endl;
}
bool is_leap_year()
{
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
return true;
}
return false;
}
int get_year()
{
return year;
}
void set_year(int new_year)
{
year = new_year;
}
protected://保护控制权限。在单个类中,跟private是一抹一样。
//在类的继承中跟private有区别,
private:
int year;
int month;
int day;
};
void test02(){
MyDate my_date;
my_date.init_date();
my_date.print_date();
if (my_date.is_leap_year() == true)
{
cout << "是闰年 " << endl;
}
else {
cout << "不是闰年 " << endl;
}
//getter,setter
cout << my_date.get_year() << endl;
my_date.set_year(2000);
cout << my_date.get_year() << endl;
}
//一个类类的内部,默认的访问控制权限是private
class Hero
{
int year;
};
//一个结构体默认的访问控制权限的是public
struct Hero2
{
int year;
void print()
{
}
};
void test03() {
Hero h;
//h.year = 1000; 报错
Hero2 h2;
h2.year = 100;
}
int main(void)
{
//test01();
test02();
test03();
return 0;
}
#endif
三、面向过程和面向对象
#if 0
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Dog
{
public:
void eat(char *food)
{
cout << name << "吃" << food << endl;
}
char name[64];
};
//面向过程
void eat(class Dog &dog, char *food)
{
cout << dog.name << "吃" << food << endl;
}
int main(void)
{
Dog dog;
strcpy(dog.name, "狗");
//过程驱动
eat(dog, "翔");
//对象驱动
dog.eat("翔");
return 0;
}
#endif
练习:
#if 1
#define _CRT_SECURE_NO_WARNINGS
#define PI 3.14
#include <iostream>
using namespace std;
//面向过程
double get_l(double r) {
return 2 * PI*r;
}
double get_s(double r) {
return PI*r*r;
}
void test01() {
cout << "面向过程" << endl;
double r = 2;
cout << "周长为:" << get_l(r) << endl;
cout << "面积为:" << get_s(r) << endl;
}
//面向对象
class Circle {
public:
Circle() {}
Circle(double r) :m_r(r) {}
void setR(double r) {
m_r = r;
}
double get_l() {
return 2 * PI*m_r;
}
double get_s() {
return PI*m_r*m_r;
}
public:
double m_r; //我 double m_r;
};
void test02() {
cout << "面向对象" << endl;
Circle c1(2);
cout << "周长为:" << c1.get_l() << endl;
cout << "面积为:" << c1.get_s() << endl;
Circle c2;
c2.setR(4);
cout << "周长为:" << c2.get_l() << endl;
cout << "面积为:" << c2.get_s() << endl;
}
class Circle2 {
public:
void setR(double r) {
m_r = r;
}
double get_l() {
return m_l;
}
double get_s() {
return m_s;
}
private:
double m_r;
double m_l= 2 * PI*m_r; //其实为2*3.14*随机数 错误
double m_s= PI*m_r*m_r; //其实为3.14*随机数*随机数 错误
};
void test03() {
Circle2 c1;
c1.setR(10);
cout << c1.get_l() << endl; //-5.81274e+62
cout << c1.get_s() << endl; //2.69013e+124
}
class Circle3 {
public:
void setR(double r) {
m_r = r;
}
double get_l() {
return 2 * PI*m_r;
}
double get_s() {
return PI*m_r*m_r;
}
private:
double m_r;
double m_l ; //其实为2*3.14*随机数 错误
double m_s ; //其实为3.14*随机数*随机数 错误
};
void test04() {
Circle3 c1;
c1.setR(10);
cout << c1.get_l() << endl; //62.8
cout << c1.get_s() << endl; //314
}
int main() {
test01();
test02();
cout << "-------------" << endl;
test03();
cout << "-------------" << endl;
test04();
return 0;
}
#endif
// demo02_circle_err.cpp
#include<iostream>
using namespace std;//c++的命名空间
class circle
{
public:
double r;
double pi = 3.1415926;
double area = pi*r*r;
};
int main(void)
{
circle pi;
cout<<"请输⼊area"<< endl;
cin >>pi.r;
cout<<pi.area<<endl; //乱码
return 0;
}
运行结果:
#include "iostream"
#define PI 3.1415926
using namespace std;
class Cricle {
public:
double m_r;
double m_s;
public:
void setR(double r) {
m_r = r;
}
double getR()
{
return m_r;
}
double getS()
{
m_s = m_r*m_r*PI;
return m_s;
}
};
int main()
{
double r1;
Cricle c1;
cout << "请输入圆的半径" << endl;
cin >> r1;
c1.setR(r1);
cout << "圆的面积为:" << c1.getS() << endl;
return 0;
}
运行结果:
不难发现有成员函数和没有成员函数答案是不一样的,为什么没有成员函数的答案会是一个乱码?
画个图来理解一下。
当给r赋值并不会影响area的值,因为当实例化类对象时,就已经为类对象的数据成员分配了空间。给r赋值,并不会影响area中初始化时的r的随机值。相互独立。
所以没有成员函数和有成员函数的相差很大。
参考自https://blog.youkuaiyun.com/sum_TW/article/details/52108421