网站首页 > 基础教程 正文
类与类之间的关系都有什么
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class A
{
public:
void func()
{
cout << "funcA" << endl;
}
int a;
private:
};
//类B拥有类A的成员变量, B has A// 类B 依赖于 类A
class B
{
public:
void funcB()
{
}
private:
A a;
};
//耦合度 高内聚 低耦合8
//类C的成员方法 需要类A的形参 C use A 类C 依赖于 类A
class C
{
public:
void funcC(A*a)
{
}
void funcC2()
{
}
private:
};
//D继承与A A中的所有代码D都可使用 类 D is A 高耦合
class D :public A
{
public:
void funcD()
{
cout << a << endl;
}
};
class E :public D
{
};
int main()
{
return 0;
}
继承的基本概念
继承指的是一个类继承另外的一个类,继承的类叫做子类,被继承的类叫做父类。
基本语法为:
class A{
};
class B:public A{
};
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
class Student
{
public:
Student(int id, string name)
{
this->id = id;
this->name = name;
}
void printS()
{
cout << "id=" << this->id << ",name=" << this->name << endl;
}
private:
int id;
string name;//使用string不必担心深拷贝问题 直接拷贝即可
};
//创建一个新的类 增加score功能
class Student2
{
public:
Student2(int id, string name, int score)
{
this->id = id;
this->name = name;
this->score = score;
}
void printS()
{
cout << "id=" << this->id << ",name=" << this->name << endl;
cout << "score=" << this->score << endl;
}
private:
int id;
string name;
//add
int score;
};
//通过继承创建一个新的学生类
class Student3 :public Student//继承 Student
{
public:
Student3(int id, string name, int score) :Student(id, name)
{
this->score = score;
}
void printS()
{
Student::printS();
cout << "score=" << this->score << endl;
}
private:
//add
int score;
};
int main()
{
Student3 s3(1, "AA", 80);
s3.printS();
return 0;
}
几种继承方式
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//规则1.只要是父类中的private中的成员,不管是什么继承方式,儿子都无法访问
//规则2.如果是public继承,儿子中的访问控制权限保持不变。
//规则3.如果是protected继承,儿子中父亲中除了protected成员,其余在儿子中均是protected
//规则4.如果是private继承,儿子中父亲除了private成员,其余在儿子中都是private成员
class Parent
{
public:
int pub;//类内部、外部军可发昂文
protected:
int pro;//类内部可以访问,外部不可访问
private:
int pri;//类内部可以访问,外部不可访问
};
//公有继承
class Child:public Parent
{
public:
void func()
{
cout << pub << endl;
//pub父类public成员变量,在public继承后类【内部、外部】均可以访问
cout << pro << endl;
//pro父类protected成员变量,在public继承后类【内部】可以访问
//cout << pri << endl;//err
//pri父类private成员变量,在public继承后【内部、外部】均不可以访问
}
private:
};
//孙子类
class SubChild:public Child
{
public:
void sub_func2()
{
cout << pro << endl;
}
};
//保护继承
class Child2 :protected Parent
{
public:
void func2()
{
pub;//此时pub通过protected继承能够在类【内部】访问
//pub 在类的内部可以访问,类外部无法访问,类的儿子可以访问
//pub 是protected成员
pro;//pro与pub性质相同 pro也是protected成员
}
private:
};
class Sub_child2:public Child2
{
public:
void sub_func2()
{
pub;
pro;
}
};
//私有继承
class Child3 :private Parent
{
public:
void func3()
{
pub;//pub在类的内部可以访问,在类的【内部】可以访问,外部不可访问。
//pub在儿子中访问不了,说明pub在child3中是私有成员
pro;//与pub相同
}
};
class Sub_Child3 :public Child3
{
public:
void sub_fun3()
{
//pub;//err
//pro;//err
}
};
int main()
{
Child c1;
c1.func();
c1.pub;
//c1.pri;//err
Child2 c2;
//c2.pub;//err
//c2.pro;//err
Child3 c3;
//c3.pub;//err
//c3.pro;//err
return 0;
}
类的兼容性赋值原则
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
/*
子类对象可以当作父类对象使用。
子类对象可以直接赋值给父类对象。
子类对象可以直接初始化父类对象.
****父类指针可以直接指向子类对象***
父类引用可以直接引用子类对象
*/
class Parent
{
public:
void printP()
{
cout << "a" << this->a << endl;
}
private:
int a;
};
class Child :public Parent
{
public:
void printC()
{
cout << "b=" << this->b << endl;
}
int b;
};
void myPrint(Parent* pp)
{
pp->printP();
}
int main()
{
// Parent p;
// Child c = p; //p对象填充不满c对象空间,
// Child c;
// Parent p = c;//c 对象所占用的内存空间 >= p对象占用空间 能够填充满p对象所需要空间。
// p = c;
// c.printP(); //c 能够当做父类 p 来使用。
Parent* pp = NULL;//父类指针
Child* cp = NULL;//子类指针
Parent p;//父类对象
Child c; //子类对象
pp = &c;//c 内存布局能够满足父类指针的全部需求, 可以用一个儿子的对象地址给父类指针赋值。
myPrint(&p);
myPrint(&c);
return 0;
}
子类的构造和析构
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Parent
{
public:
Parent()
{
cout << "Parent().." << endl;
a = 0;
}
Parent(int a)
{
cout << "Parent(int).." << endl;
this->a = a;
}
~Parent()
{
cout << "~Parent" << endl;
}
int a;
};
class Child :public Parent
{
public:
//在调用子类的构造函数的时候,一定会调用父类的构造函数
Child(int a, int b):Parent(a)
{
cout << "Child(int ,int).." << endl;
this->b = b;
}
void printC()
{
cout << "b=" << b << endl;
}
~Child()
{
cout << "~Child().." << endl;
}
int b;
};
int main()
{
Child c(10, 20);
c.printC();
return 0;
}
当子类和父类成员重名
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Parent
{
public:
Parent(int a)
{
this->a = a;
}
int a;
};
class Child:public Parent
{
public:
Child(int p_a,int c_a):Parent(p_a)
{
this->a = c_a;
}
void print()
{
cout << Parent::a << endl;
cout << this->a << endl;
}
int a;
};
int main()
{
Child c(10, 100);
c.print();
return 0;
}
继承中的static
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class A
{
public:
static int a;
private:
};
class B :public A
{
public:
private:
};
int A::a = 100;//静态成员变量的初始化
int main()
{
A a1;
A a2;
cout << a1.a << endl;
cout << a2.a << endl;
A::a = 200;
cout << a1.a << endl;
cout << a2.a << endl;
B b1;
B b2;
A::a = 300;
cout << "--------" << endl;
cout << b1.a << endl;
cout << b2.a << endl;
cout << a1.a << endl;
cout << a2.a << endl;
return 0;
}
多继承与虚继承
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//家具类
class Furniture
{
public:
int m;//材质
};
//virtual 虚继承 防止多子继承后出现多个爷爷中的变量重复拷贝
class Bed:virtual public Furniture
{
public:
void sleep()
{
cout << "在床上睡觉" << endl;
}
};
//虚继承
class Sofa:virtual public Furniture
{
public:
void sit()
{
cout << "在沙发休息" << endl;
}
};
//沙发床
class SofaBed:public Bed,public Sofa//多继承
{
public:
void SleepAndSit()
{
sleep();
sit();
}
};
int main()
{
Bed b;
b.sleep();
Sofa s;
s.sit();
cout << "----------" << endl;
SofaBed sb;
sb.SleepAndSit();
sb.m = 100; //虚继承后只有一个m
//sb.Bed::m=100;
//sb.Sofa::m=200;
return 0;
}
多态
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
//岳不群
class Yuebuqun
{
public:
Yuebuqun( string kongfu)
{
this->kongfu = kongfu;
}
virtual void fight()//表示这是一个虚函数
{
cout << "岳不群"<<"使用了" << kongfu << "打人" << endl;
}
string kongfu;
};
//林平之
class Linpingzhi:public Yuebuqun
{
public:
Linpingzhi(string kongfu) :Yuebuqun( kongfu)
{
}
//
void fight()
{
cout<<"岳不群"<<"使用了" << kongfu << "打人" << endl;
}
};
class Linghuchong :public Yuebuqun
{
public:
Linghuchong(string kongfu) :Yuebuqun(kongfu)
{
}
void fight()
{
cout << "令狐冲" << "使用了" << kongfu << endl;
}
};
//在全局提供一个打斗方法
void fightPeople(Yuebuqun*hero)
{
cout << "调用打人的方法" << endl;
hero->fight();
//希望传进来的若是子类,调用子类fight
//传进来的是父类,调用父类fight
//这就是 多态 行为
}
//多态发生的三个必要条件:
// 1.要有继承
// 2.要有虚函数 (virtual)
// 3.父类指针或引用指向子类对象
int main()
{
Yuebuqun* YY = new Yuebuqun("葵花宝典");
YY->fight();
delete YY;
Linpingzhi* PP = new Linpingzhi("辟邪剑谱");
PP->fight();
delete PP;
Linghuchong* LL = new Linghuchong("独孤九剑");
fightPeople(YY);
fightPeople(PP);
fightPeople(LL);
delete PP;
return 0;
}
多态的案例和意义
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
//英雄类
class Hero
{
public:
virtual int getAd()
{
return 10;
}
};
class AdvHero:public Hero
{
public:
virtual int getAd()
{
return 1001;
}
};
//怪兽类
class Monster
{
public:
int getAd()
{
return 1000;
}
};
//战斗方法
//版本1 写的架构函数可以调用未来
void playerFight(Hero* hp, Monster* mp)
{
if (hp->getAd()>mp->getAd())//hp->getAd发生多态
{
cout << "英雄胜利" << endl;
}
else
{
cout << "英雄失败,怪兽胜利" << endl;
}
}
//升级后 版本2
class BugHero:public Hero
{
public:
virtual int getAd()
{
cout << "调用了bughero的方法" << endl;
return 88888;
}
};
int main()
{
Hero h;
Monster m;
playerFight(&h, &m);
AdvHero advH;
playerFight(&advH, &m);
BugHero bh;
playerFight(&bh, &m);
return 0;
}
虚析构函数
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class A
{
public:
A()
{
cout << "A().." << endl;
this->p = new char[64];
memset(this->p, 0, 64);
strcpy(this->p, "A string..");
}
virtual void print()
{
cout << "A: " << this->p << endl;
}
virtual~A()
{
cout << "~A().." << endl;
if (this->p!=NULL)
{
delete[]this->p;
this->p = NULL;
}
}
private:
char* p;
};
class B:public A
{
public:
B()
{
cout << "B().." << endl;
}
virtual void print()
{
cout << "B: " << this->p << endl;
}
virtual~B()
{
cout << "~B().." << endl;
if (this->p!=NULL)
{
delete[]this->p;
this->p = NULL;
}
}
private:
char* p;
};
void func(A* ap)
{
ap->print();//在此发生多态
delete ap;
}
void test()
{
A aObj;
func(&aObj);
B bObj;
}
int main()
{
test();
return 0;
}
/*
重载、重写与重定义
1.重载 一定在同一作用域下相同函数名,不同形参列表
2.重定义:
发生在两个不同的类中,一个父类、一个子类
普通函数重定义 如果父类的普通成员函数,被子类重写,就是重定义
3.重写:虚函数重写。
如果父类的虚函数,被子类重写,就是虚函数重写,会发生多态。
*/
- 上一篇: C++11:继承构造函数 cpp继承构造函数
- 下一篇: c++函数参数和返回值 c语言函数返回参数
猜你喜欢
- 2024-10-10 C++系列1-1:初探C++ c=2μf
- 2024-10-10 浅谈C++11(第9篇 可变参数模板) c++可变参数模板类
- 2024-10-10 数组的初始化方式有哪几种? 数组的初始化是什么意思
- 2024-10-10 c++对于内建类型的默认初始化 创建内部类的对象
- 2024-10-10 C++类构造函数,如何初始化对象?linux C++第27讲
- 2024-10-10 【C++编程语言】之 类和对象——对象的初始和消除
- 2024-10-10 C++基础语法梳理:引用、封装、继承和多态
- 2024-10-10 C++核心准则?:按照成员声明的顺序定义和初始化成员变量
- 2024-10-10 C++核心准则C.47:按照成员变量声明的次序定义和初始化数据成员
- 2024-10-10 C/C++语言编程系列002——不同情况下数组的初始化方法
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)