当前位置: 首页 > news >正文

网站建设有哪些软件有哪些方面网站开发一般流程图

网站建设有哪些软件有哪些方面,网站开发一般流程图,广告联盟app手机版,mvc 网站开发🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 多态 多态就是不同类型的对象,去做同一个行为,但是产生的结果是不同的。 比如说: 都是动物叫声,猫是喵喵,狗是汪汪&am…

🌈个人主页:羽晨同学 

💫个人格言:“成为自己未来的主人~”  

多态

多态就是不同类型的对象,去做同一个行为,但是产生的结果是不同的。

比如说:

都是动物叫声,猫是喵喵,狗是汪汪,它们的叫声是不相同的。

多态的定义和实现

多态的构成条件

多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。

在继承中,构成多态需要两个条件:

  1. 必须通过基类的指针或者引用调用虚函数。
  2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。
class Person 
{
public:virtual void BuyTicket(){cout << "买票-全价" << endl;}
};
class Student:public Person
{//重写/覆盖virtual void BuyTicket(){cout << "买票-半价" << endl;}
};
class Soldier:public Person
{
public://重写/覆盖virtual void BuyTicket(){cout << "买票-优先" << endl;}
};
//多态条件
//1.虚函数重写
//2.父类指针或者引用调用虚函数
void func(Person& p)
{p.BuyTicket();
}
int main()
{Person p;Student st;Soldier so;func(st);func(so);return 0;
}

你看,这样子就实现了多态。

虚函数

被virtual修饰的函数就叫做虚函数

class Student:public Person
{//重写/覆盖virtual void BuyTicket(){cout << "买票-半价" << endl;}
};

虚函数的重写

虚函数的重写(覆盖):派生类和基类中的某个函数函数名相同,参数相同,返回值相同,就称子类的虚函数重写了基类的虚函数。

class Person 
{
public:virtual void BuyTicket(){cout << "买票-全价" << endl;}
};
class Student:public Person
{//重写/覆盖virtual void BuyTicket(){cout << "买票-半价" << endl;}
};
class Soldier:public Person
{
public://重写/覆盖virtual void BuyTicket(){cout << "买票-优先" << endl;}
};

你看,这样其实就是标准的构成了函数重写的代码。

但是,由于继承的存在,所以,其实派生类不写virtual也会构成函数重写。

class Person 
{
public:virtual void BuyTicket(){cout << "买票-全价" << endl;}
};
class Student:public Person
{//重写/覆盖virtual void BuyTicket(){cout << "买票-半价" << endl;}
};
class Soldier:public Person
{
public://重写/覆盖void BuyTicket(){cout << "买票-优先" << endl;}
};

比如上面的这样,但是这样子是不规范的,所以我们最好加上virtual。

虚函数重写的两个例外:

协变(基类和派生类的返回值类型不同)

派生类重写基类虚函数时,与基类虚函数返回值类型不同,即基类虚函数返回基类对象的指针或者引用,派生类对象返回派生类对象的指针或者引用,这个就叫做协变。

class A{};
class B :public A {};class Person 
{
public:virtual A* BuyTicket(){cout << "买票-全价" << endl;return 0;}
};
class Student:public Person
{//重写/覆盖virtual B* BuyTicket(){cout << "买票-半价" << endl;return 0;}
};
class Soldier:public Person
{
public://重写/覆盖virtual B* BuyTicket(){cout << "买票-优先" << endl;return 0;}
};
//多态条件
//1.虚函数重写
//2.父类指针或者引用调用虚函数
void func(Person& p)
{p.BuyTicket();
}
int main()
{Person p;Student st;Soldier so;func(st);func(so);return 0;
}

这样子,我们就实现了协变。

析构函数的重写

我们先来看一下下面的这段代码:

class Person
{
public:virtual ~Person(){cout << "virtual ~Person()" << endl;}
};
class Student:public Person
{
public:protected:int* _ptr = new int[10];
};
int main()
{Person* p1 = new Student;delete p1;return 0;
}

在这段代码当中,我们删除了p1,但是结果调用的是基类的析构函数。

那为什么会这样呢,是因为编译器对析构函数的名字做了特殊的处理,编译后的析构的名字同一处理为了destructor;这样子的话,基类和父类的析构函数就构成了隐藏。

这样子调用的话,那么会造成内存泄漏。

但是,只要我们构成了多态,那么就解决了这个问题。

class Person
{
public:virtual ~Person(){cout << "virtual ~Person()" << endl;}
};
class Student:public Person
{
public:virtual ~Student(){cout << "virtual ~Student()" << endl;}
protected:int* _ptr = new int[10];
};
int main()
{//Student st;Person* p1 = new Student;delete p1;Person* p2 = new Person;delete p2;return 0;
}

override 和final

上面可以看出,C++对函数重写的要求比较严格,但是有些情况下由于疏忽,可能会导致函数字母次序写反而无法构成重写,这种错误在编译期间是无法报出的,只有在程序运行时没有到预期结果才会debug,这样子得不偿失。 

final:修饰虚函数,表示该虚函数不能再被重写

class A final
{
public:static A CreatObj(){return A();}
private:A(){};
};
class V:public A
{};
int main()
{A::CreatObj();return 0;
}

所以,在这个代码中,会出现报错的问题。

override:检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错

class Car {
public:virtual void Drive() {}
};
class Benz :public Car {
public:virtual void Drive() override { cout << "Benz-舒适" << endl; }
};
int main()
{Car a;return 0;
}

重载,覆盖(重写),隐藏(重定义)的对比

重载:

两个函数在同一个作用域。

函数名相同,参数不同。

重写(覆盖)

两个函数分别在基类和派生类的作用域。

函数名,参数,返回值都必须相同(协变除外)

两个函数必须是虚函数

重定义

两个函数分别在基类和派生类的作用域

函数名相同

来年各个基类和派生类的同名函数不构成重写就是重定义

抽象类

在虚函数后面写上=0,则这个函数为纯虚函数,包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象,纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承。

class Car
{
public:virtual void Drive() = 0;
};
class Benz :public Car
{
public:virtual void Drive(){cout << "BWM-舒适" << endl;}
};
class BWM :public Car
{
public:virtual void Drive(){cout << "BWM-操控" << endl;}
};
int main()
{Car a;Benz bz;return 0;
}

在这个代码中,因为基类中有纯虚函数,所以不能实例化出对象,而派生类中对纯虚函数进行了重写,所以可以进行实例化。

多态的原理

虚函数表

class Base
{
public:virtual void Func1(){cout << "Func1()" << endl;}
private:int _b = 1;
};
int main()
{cout<<sizeof(Base);return 0;
}

大家可以想一想这个结果是什么。

答案是8,那么,这是为什么呢?

我们来仔细看一下Base里面有什么。

我们可以看到的是在这里面还存在了一个虚函数表的指针,这个就是存放虚函数的地址的地方。

 

class Base
{
public:virtual void func1(){cout << "Base::func1()" << endl;}virtual void func2(){cout << "Base::func2()" << endl;}void func3(){cout << "Base::func3()" << endl;}
private:int _b = 1;
};
class Derive : public Base
{
public:virtual void func1(){cout << "Derive::Func1()" << endl;}
private:int _d = 2;
};
void func1(Base* p)
{p->func1();p->func3();
}
int main()
{Base b;Derive d;func1(&b);func1(&d);return 0;
}

  • 通过这个结果,我们可以得到的是,派生类中也有一个虚表的指针,里面存放的有两部分,一个是自己的成员,一个是从基类继承下来的成员。
  • 基类b对象和派生类d对象虚表是不一样的,我们这里发现func1完成了重写,所以d中存放的是Derieve::Func1();,所以虚函数的重写也叫覆盖。
  • 不是虚函数,函数的指针不会被放进虚表
  • 虚表存放在对象里面,虚表里面存放的是虚函数的指针,虚函数存放在代码段那里。

满足多态以后的函数调用,不是在编译时确定的,是运行起来以后到对象中的找的,不满足多态的函数调用是编译时就确认好的。

动态绑定和静态绑定

在程序编译期间确定了程序的行为,叫做静态绑定。

在程序运行期间,在对象中找的行为,叫做动态绑定

好了,本次的文章就到这里了,我们下次再见。 

http://www.yayakq.cn/news/194780/

相关文章:

  • 网站规划和建设中企动力建站怎么样
  • 网站怎么加友情链接一个公司可以有两个网站吗
  • wordpress建站安全性搜索引擎排名中国
  • 建网站 是否 数据库wordpress哪个主题好
  • 中国免费网站服务器网页设计报告2000字
  • 上海企业网站seo多少钱织梦系统网站首页空白
  • 做网站好深圳网站建设制作哪家口碑好
  • 菏泽市住房和城乡建设路网站网站作业二级网页
  • 无锡个人网站建设为企业做网站赚钱吗
  • 网站建设纟金手指下拉壹陆可口可乐营销策划方案
  • 吉安做网站的网页美工设计的流程有哪些?
  • 网站首页ui大学生个人网站模板
  • 上海网站排名优化费用平面广告设计要用什么软件有哪些
  • 网站的建设方式有哪些wordpress 文字排版
  • 网站建设新媒体运营杨凌网站开发
  • 品牌网站建设哪里好wordpress无法安装
  • 申请免费网站哪个好做网站赚钱吗
  • 天津企业网站建设开发维护wordpress安装主题后不够
  • 佛山专业网站建设的公司html5标签
  • 南海佛山网站建设如何制作网页效果图
  • 建设淘宝客网站南昌模板建站代理
  • 如何学好网站建设qq网站代码
  • 福清做网站的公司贵州省铜仁市城乡建设局网站
  • 推荐几个没封的网站上海所有公司名称
  • 网站托管找东莞网站设计公司淘宝
  • 鲜花网站怎么做工程承包资质有哪些
  • 360平台怎么做网站优化微信怎么建立公众号小程序
  • 腾讯网站如何设计一个企业
  • 襄阳网站制作电脑培训学校在哪里
  • 贡井区建设局网站深圳ui设计