#include
#include
using namespace std;
const double PI = 3.14;
//第一个
//
//class circle {
// public://公共的访问权限
// //属性
// int r;
// //行为
// double calculate() {
// return 2 * PI * r;
// }
//
//};
//
//int main() {
// circle cl;
// cl.r = 10;
// cout << "圆的周长" << cl.calculate() << endl;
//}
//第二个
//class Student {
// public:
// string name;
// int number;
// void showstudent() {
// cout << "学生的姓名" << name << "学生的学号" << number << endl;
// }
// void setstudent(string my_name){
// name=my_name;
// }
//};
//
//int main() {
// Student zyc;
// cout << "请输入学生姓名与学号" << endl;
// cin >> zyc.name >> zyc.number;
// zyc.showstudent();
// zyc.setstudent("张宇超");//赋值函数,行为给属性赋值
//
// Student zbc;
// cout << "请输入学生姓名与学号" << endl;
// cin >> zbc.name >> zbc.number;
// zbc.showstudent();
//}
//第三个
//访问权限 public 公共权限类内类外都可访问
// protected公共权限类内可以 类外不可,儿子可以访问
// private公共权限类内可以 类外不可,儿子不可以访问,类外就是在calss之外的
//struct与class访问权限不同,struct默认权限工共,class默认私有
//private的意义可读可写的控制,用public的方法来处理
//class student {
// public:
// void showfood() {
// cout << food << endl;
// }
// void setfood(string a_food) {
// food = a_food;
// }
// void showage() {
// cout << "学生年龄为" << age << endl;
// }
// void setage() {
// cout << "请输入年龄" << endl;
// cin >> age;
// if (age < 0 || age > 150) {
// cout << "你输入的年龄有误" << endl;
// return ;
// }
//
// }
// void setlove(string a_love) {
// love = a_love;
// }
// private:
// string food;//可读可写
// int age = 18 ; //可读
// string love;//可写
//};
//
//int main () {
//
// student p;
// p.setfood("宫保鸡丁");//可写的设置
// p.showfood();//可读的设置
// p.setage();
// p.showage();
// p.setlove("张宇超");
//}
构造函数,析构函数,他们不要返回值,没void,不写的话系统自己整2个,函数名与类名一致,构造函数可以有参数,析构函数不可以有参数名字前有~来区分两个
分类:1有参无参2普通构造,拷贝构造
//class person {
// public:
// person() {
// cout << "无参构造函数" << endl;
// }
// person(int a,int height) {
// cout << "有参构造函数" << endl;
// age = a;
// m_height=new int(height);//堆区
// }
// person(const person &p) {
// cout << "拷贝构造函数" << endl;
// age = p.age;//浅拷贝
// m_height=new int(*p.m_height);//深拷贝
// }
// ~person() {
// //将堆区开辟的数据释放
// if(m_height!=NULL){
// delete m_height;
// m_height=NULL;
// }
//
//
//
// cout << "析构函数" << endl;
// }
//
// int age;
// int *m_height;
//
//};
值的方式传数据,值的方式返回都会调用拷贝构在函数
//int main() {
// person p;//注意调用默认构造不能加()
// person p2(10);
// person p3(p2);
//}
创建一个类,系统默认给三个函数给、拷贝,析构,默认
如果写了有参构造,系统自己给拷贝,不给默认
如果写了拷贝,有参,默认都不提供
//class person {
// public:
// person(int a, int b, int c): m_A(a), m_B(b), m_C(c) {
// }
注意冒号
// void show() {
// cout << "m_A:" << m_A << endl;
// }
// private:
// int m_A;
// int m_B;
// int m_C;
//
//};
//
//int main () {
// person p(1, 2, 3);
// p.show();
//}
不属于某个对象(实例)所有对象共享同一个数据,类内声明类外初始化,编译阶段分配内存
//静态成员函数:所有对象共享同一个函数,并且只能访问静态成员变量
//class person {//他们两个必须public,存在访问权限,private不行
// public:
// static int m_a;
// static void func(){
// m_a=3000;//可以访问静态成员
// cout<<"静态函数的调用"<
//};
//int person:: m_a = 100; //类外初始化
//
//void test01() {
// person p;
// cout << p.m_a << endl;
// person p2;
// p2.m_a = 200;
// cout << p.m_a << endl; //200结果
//}
//
//void test02() {
访问方式2种,通过对象;通过类名
// person p2;
// p2.func();
// cout << p2.m_a << endl;
//
// person::func();
// cout << person::m_a << endl;
//}
//
//int main() {
// test01();
// test02();
//}
成员变量成员函数分开存储,只有非静态成员属于类的对象上
空对象占用内存空间1,因为要区分不同的空对象占内存位置,不能沾重复位置
//class person {
// public:
// // int m_a;//非静态成员,属于类的对象上
// static int m_b;//静态成员和函数,不属于类的对象上
//};
//int person::m_b;
//
//int main () {
// person p;
//
// cout << "sizeof(p)为" << sizeof(p) << endl;
cout << "sizeof(m_a)为" << sizeof(p.m_a) << endl;
// cout << "sizeof(m_b)为" << sizeof(p.m_b) << endl;
//}
//
解决名称冲突(形参与成员属性区分),返回对象本身
//class person {
// public:
// person(int age) {
// this ->age = age;//this指针指向的是谁掉的有参构造,就指向谁
// }//这里指向P
// void personaddage(person p) {
// this->age += p.age;
// }
// person& personaddage1(person p) {//&是引用,返回的是一个对象,如果不加每次返回的都是新的,从而无法实现累加
// this->age += p.age;
// return *this;//this是指向p的指针,加*就成了本体,实现链式编程
// }
// int age;
//};
//
//int main() {
// person p(10);
// person p1(10);
// p1.personaddage(p);
// cout << "p1的年纪是" << p1.age << endl;
// p1.personaddage1(p).personaddage1(p).personaddage1(p);
// cout << "现在p1的年纪是" << p1.age << endl;
// cout << p.age << endl;
//}
//if(this==NULL){
// return;
//}
//class person{
// public:
// void showperson()
// {
// m_a=100;
// }
// int m_a;
//};
//int main(){
//
//}
全局函数佐友元,能够访问私有
//class Building {
// friend void goodgay(Building *p);
// public:
// Building() {
// m_sittingroom = "客厅";
// m_bedroom = "卧室";
// }
// string m_sittingroom;
// private:
// string m_bedroom;
//
//};
//
//void goodgay(Building *p) {
// cout << "好友在访问" << p->m_sittingroom << endl;
// cout << "好友在访问" << p->m_bedroom << endl;
//}
//
//int main() {
// Building p;
// goodgay(&p);
//}
//类做友元
//class Building {
// friend class Goodgay;
// public:
// Building() {
// this->m_sittingroom = "餐厅";
// this->m_bedroom = "卧室";
//
// }
// string m_sittingroom;
// private:
// string m_bedroom;
//};
//
//class Goodgay {
// public:
// Goodgay() {
// building = new Building;
// }
// void visit() {
// cout << "好基友正在访问" << building->m_sittingroom << endl;
// cout << "好基友正在访问" << building->m_bedroom << endl;
// }
private:
// Building *building;
//};
//
//
//void test01() {
// Goodgay gg;
// gg.visit();
//}
//
//int main() {
//
// test01();
//}
加号,实现两个类相加
//class person {
// public:
//方式1、成员函数内部重载
person operator+(person &p) {
person temp;
temp.m_a = this->m_a + p.m_a;
temp.m_b = this->m_b + p.m_b;
return temp;
}
// int m_a;
// int m_b;
//};
//
方式二,全局函数重载+号
//person operator+(person &p1, person &p2) { //最前面o\person,是返回值类型
// person temp;
// temp.m_a = p1.m_a + p2.m_a;
// temp.m_b = p1.m_b + p2.m_b;
// return temp;
//}
//
//person operator+(person &p1, int num) {
// person temp;
// temp.m_a = p1.m_a + num;//两个函数名字一样,参数不同,叫函数重载
// temp.m_b = p1.m_b + num;
// return temp;
//}
//
//void test01() {
// person p1;
// p1.m_a = 10;
// p1.m_b = 10;
// person p2;
// p2.m_a = 10;
// p2.m_b = 10;
// person p3 = p1 + p2;
// cout << "p3.m_a是" << p3.m_a << endl;
// cout << "p3.m_b是" << p3.m_b << endl;
// person p4 = p1 + 100;
// cout << "p4.m_a是" << p4.m_a << endl;
// cout << "p4.m_b是" << p4.m_b << endl;
//}
//
//int main () {
// test01();
//}
//左移运算符重载,只能用全局函数,现在目的输入对象本身,输出全部属性
//class person {
// friend ostream &operator<<(ostream &cout, person &p); //这样可以访问private;
// public:
// person(int a, int b) {
// m_a = a;
// m_b = b;
// }
// int m_a;
// int m_b;
//};
//
//ostream &operator<<(ostream &cout, person &p);
//
//void test01() {
// person p(10, 10);
p.m_a = 10;
p.m_b = 10;
//
// cout << p << "hello" << endl;
cout << p;想在后面继续添加,就使用链式思想,不断返回对象本身
//}
//
//ostream &operator<<(ostream &cout, person &p) {
// cout << "m_a=" << p.m_a << "m_b=" << p.m_b << endl;
// return cout;
//}
//
//int main() {
// test01();
//
//}
重载运算符,实现自己写一个int
//class Myinteger {
// friend ostream &operator<<(ostream &cout, Myinteger myint);
// public:
// Myinteger() {
// m_num = 0;
// }
// private:
// int m_num;
//};
//
此函数处理<<输出自己int的数据
//ostream &operator<<(ostream &cout, Myinteger myint) {
// cout << myint.m_num;
// return cout;
//}
//
重载前置运算符++a
//Myinteger &operator++() {
// m_num++;//先进行++运算
// return *this;//前置返回自身
//}
//
//
Myinteger operator++(){
m_num++;//先进行++运算
return *this;//返回自身
}如果返回值不加引用,在++的基础上在做++每次返回是新值,最终返回该数据只是加了一次的数据
重载后置运算符a++,这里函数重载出问题,不可以用返回值不同区分函数
//Myinteger operator++(int) { //这里加int表示占位参数,用于区分前置与后置
// //先返回
// Myinteger temp = *this; //记录当前的值,然后让本身加1,但是返回的是以前的值m_num++;
// //后++
// m_num++;
// return temp;//后置返回值
//}
//
//void test01() {
// Myinteger myint;
// cout << myint << endl;
// cout << ++myint << endl;
// cout << myint++ << endl;
//}
//
//
//
//int main() {
// test01();
//}
//赋值运算符重载
//class person {
// public:
// person(int age) {
// m_age = new int(age);//数据创建在堆区,手动开辟
// }
// ~person() {
// if (m_age != NULL) {
// delete m_age;
// m_age = NULL;
// }
// }
// int *m_age;
//};
//
//person &operator=(person &p) {
// //编译器提供浅拷贝
this->m_age=p.m_age
应先判断是否有属性在堆区,如果有先释放干净再深拷贝
// if (m_age != NULL) {
// delete m_age;
// m_age = NULL;
// }
深拷贝
//
// m_age = new int(*p.m_age);
返回对象本身
// return*this;
//}
//
//void test01() {
// person p1(18);
// person p2(20);
// person p3(30);
// p2 = p1;
// cout << "p1的年龄是" << *p1.m_age << endl;
// cout << "p2的年龄是" << *p2.m_age << endl;
// //连续时,要返回对象本身
// p3 = p2 = p1;
//}
//
//int main () {
//
// test01();
//}
//关系运算符重载
//class person {
// bool operator==( person &p) {
// if (this->m_name == p.m_name && this->m_age == p.m_age) {
// return true;
// } else {
// return false;
// }
//}
// public:
// person(int age, string name) {
// m_age = age;
// m_name = name;
// }
// int m_age;
// string m_name;
//};
//int main () {
// person p1(10, "tom");
// person p2(20, "jerry");
// if (p1 == p2) {
// cout << "相等" << endl;
// } else {
// cout << "不相等" << endl;
// }
//}
//函数调用运算符重载,仿函数灵活多变,没固定格式
//class Myprint {
// public:
// void operator()(string a) {
// cout << a << endl;
// }
// int operator()(int num1, int num2) {//函数重载
// return num1 + num2;
// }
//};
//int main() {
// Myprint myprint;
// myprint("张宇超");
// cout << myprint(100, 200) << endl;
//}
//继承:class 子类/派生类:继承方式 父类/基类
//class BasePage {
// public:
// void head() {
// cout << "首页,公开课" << endl;
// }
// void foot() {
// cout << "交流中心,互助" << endl;
// }
//
//
//};
//
//class java: public BasePage {
// public:
// void content() {
// cout << "java学科视频" << endl;
// }
//
//};
//
//class cpp: public BasePage {
// public:
// void content() {
// cout << "c++学科视频" << endl;
// }
//
//};
//
//int main() {
// //java页面
// cout << "java如下" << endl;
// java ja;
// ja.content();
// ja.foot();
// ja.head();
// cout << "-------------- " << endl;
// //cpp页面
// cout << "c++如下" << endl;
// cpp cp;
// cp.content();
// cp.foot();
// cp.head();
// cout << "-------------- " << endl;
//}
继承方式,
//class A{
// public:int a;
// protected: int b;
// private: int c;
//};
公有继承
//class B:public A{
// public:int a;
// protected:int b;
// //父类中私有不可访问
//};
保护继承
//class B:protected A{
// protected:int a;
// int b;
// //父类中私有不可访问
//};
私有继承
//class C:private A{
// private:int a;
// int b;
// //父类中私有不可访问
//};
//父类的属性都属于子类,只是private无法访问
//打开vs的开发人员命令提示符
//盘名称:\cd 文件路径
//下一行写dir
//最后cl /d1 reportSingleClassLayout查看的类名 所属文件夹(tap自动补全)
//继承中构造析构顺序
//直接调用son s;
//父类构造,子类构造,子类析构,父类析构
//继承中同名成员处理方式
//class Base{
// public:
// Base(){
// m-a=100;
// }
// int m-a;
//};
//class son:public Base{
// public:
// son(){
// m-a=200;
// }
// int m-a;
//};
//int main(){
// son s;
// //字类对象直接访问子类成员
// cout<<"son下的m-a等于"<
// cout<<"base下的m-a等于"<
//继承中同名静态成员处理方式,与非静态差不多,只不过多出一种类名直接访问
//首先,静态成员特点:1数据属于类,所有对象共享2编译分配内存3类内声明类外初始化
//静态函数只能调用静态成员,子类同名函数会隐藏所有父类同名,无论是否重载,调父类都必须加作用域
//class Base {
// public:
// static int m_a;
// static void func() {
// cout << "Base static void func()的访问";
// }
//};
//int Base::m_a = 100;
//
//class son: public Base {
// public:
// static int m_a;
// static void func() {
// cout << "son static void func()的访问";
// }
//};
//int son::m_a = 200;
同名静态成员属性
//void test01() {
// //1~通过对象访问
// son s;
// cout << "通过对象" << endl;
// cout << "son下的m_a" << s.m_a << endl;
// cout << "Base下的m_a" << s.Base::m_a << endl;
// //2`通过类名访问
// cout << "通过类名" << endl;
// cout << "son下的m_a是" << son::m_a << endl;
// cout << "直接访问Base类的m_a是" << Base::m_a << endl;
// //第一个是通过类名方式访问第二个是访问父类作用域下
// cout << "通过son访问Base的m_a是" << son::Base::m_a << endl;
//}
//
同名静态成员函数
//void test02() {
// //通过对象
// cout << "函数通过对象" << endl;
// son p;
// p.func();
// p.Base::func();
// //通过类名
// cout << "函数通过类名" << endl;
// son::func();
// son::Base::func();
//}
//
//int main () {
// test01();
// test02();
//}
//多继承语法(认多个爹)
//class 子类:继承方式 父类1,继承方式 父类2,.。。。。
//大概率出现父类同名成员,加上作用域
//两个父类
//class Base1 {
// public:
// int m_a;
// Base1() {
// m_a = 100;
// }
//};
//
//class Base2 {
// public:
// int m_a;
// Base2() {
// m_a = 200;
// }
//};
//
子类
//class son: public Base1, public Base2 {
// public:
// son() {
// m_c = 300;
// m_d = 400;
// }
// int m_c;
// int m_d;
//};
//
//void test01() {
// son s;
// sizeof(s);//这里再视频中重新讲了命令提示符
Base1与2同名成员时,加作用域
// cout << "Base1里面的m_a是" << s.Base1::m_a << endl;
// cout << "Base2里面的m_a是" << s.Base2::m_a << endl;
//}
//
//int main () {
// test01();
//}
//菱形继承,比如羊与驼子都继承动物类,羊驼继承羊和驼子,再分别给
class animal {
public:
int m_age;
};//利用虚继承解决菱形问题
//原理是现在不是继承两份数据,而实继承两份指针,通过偏移量找到唯一数据
//animal叫虚基类
class sheep: virtual public animal {
};
class tuo: virtual public animal {
};
class sheeptuo: public sheep, public tuo {
};
int main() {
sheeptuo st;
st.sheep::m_age = 18;
st.tuo::m_age = 28;
//此时st.m_age会有歧义,直接访问m_age出错,两个父类有歧义加作用域区分
cout << "st.sheep::m_age是" << st.sheep::m_age << endl;
cout << "st.tuo::m_age是" << st.tuo::m_age << endl;
cout << st.m_age << endl; //用虚继承之后解决菱形问题,可以直接访问
//这份数据有一份就行,菱形继承导致资源浪费有两份
}