一、类和对象
面向对象三大特点:封装、继承、多态。
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,settercout << 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+62cout << 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.8cout << 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.csdn.net/sum_TW/article/details/52108421