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

阿里巴巴网站怎样做的漂亮深圳做网站的

阿里巴巴网站怎样做的漂亮,深圳做网站的,专业公司网站 南通,广州魔站建站目录 一、继承概念与定义 1.1、什么是继承? 1.2、继承定义 二、继承关系与访问限定符 2.1、继承方式 三、基类与派生类对象的赋值转换 3.1、向上转型 3.2、对象切片 四、继承中的作用域 4.1、隐藏 五、派生类中的成员函数 5.1、构造与析构 六、继承与友…

目录

一、继承概念与定义

1.1、什么是继承?

1.2、继承定义

二、继承关系与访问限定符

2.1、继承方式

三、基类与派生类对象的赋值转换

3.1、向上转型

3.2、对象切片

四、继承中的作用域

4.1、隐藏

五、派生类中的成员函数

5.1、构造与析构

六、继承与友元、静态成员

6.1、友元关系不可继承

6.2、静态成员共享

七、复杂的菱形继承与虚拟继承

7.1、菱形继承问题

7.2、虚拟继承

7.2.1、解决原理

八、继承与组合:如何选择?

1. 继承("is-a"关系)

2. 组合("has-a"关系)

3. 选择原则


一、继承概念与定义

1.1、什么是继承?

简单来说:继承就像现实中的父子关系。孩子继承父母的特征(如眼睛),但孩子也可以有自己的独特属性(如头发)。

而在代码中,继承是子类继承父类的字段和方法,同时可以添加新功能或覆盖父类的方法。

继承是面向对象编程中的一个核心机制,它允许一个类(子类/派生类)基于另一个类(父类/基类)来定义,从而自动获取父类的属性和方法,并可以在此基础上进行扩展或修改。

继承优势?

避免重复编写相同的代码。父类的通用逻辑只需要写一次,子类可以直接继承。减少了代码量。

比如:

class Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}
protected:string _name = "peter"; // 姓名int _age = 18;  // 年龄
};class Student : public Person
{
protected:int _stuid; // 学号
};class Teacher : public Person
{
protected:int _jobid; // 工号
};int main()
{Student s;Teacher t;s.Print();t.Print();return 0;
}

上面代码可以看出对于“老师”和“学生”来说都具有“人”的属性,所以这里Student和Teacher都继承了Person这个类,继承后父类的Person的成员(成员函数+成员变量)都会变成子类的一部分。可以通过调试窗口看出来:

1.2、继承定义

Person是父类,也称作基类。Student是子类,也称作派生类。


二、继承关系与访问限定符

2.1、继承方式

C++支持三种继承方式:public、protected、private,它们决定了基类成员在派生类中的可见性:

基类成员访问权限public继承                        protected继承private继承
基类的public成员派生类的public成员派生类的protected 成员派生类的private 成员
基类的protected 成员派生类的protected 成员派生类的protected 成员派生类的private 成员
基类的private成 员在派生类中不可见在派生类中不可见在派生类中不可见

1. 基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它

比如:

class Base 
{
public:int a;
protected:int b;
private:int c;
};class Derived : private Base 
{ // a → private, b → private, c不可见(就是不能访问父类的成员)
};

2. 基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。

3. 在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里面使用,实际中扩展维护性不强。 


三、基类与派生类对象的赋值转换

3.1、向上转型

派生类对象可以直接赋值给基类的对象、基类指针或引用。基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针是指向派生类对象时才是安全的。

int main()
{Student sobj ;Person pobj = sobj; // 合法Person* pp = &sobj; // 合法Person& rp = sobj; // 合法sobj = pobj;//非法// 3.基类的指针可以通过强制类型转换赋值给派生类的指针pp = &sobjStudent* ps1 = (Student*)pp; // 这种情况转换时可以的。ps1->_No = 10;pp = &pobj;Student* ps2 = (Student*)pp; // 这种情况转换时虽然可以,但是会存在越界访问的问题ps2->_No = 10;return 0;
}

3.2、对象切片

向上转型有个形象的说法叫切片或者切割。寓意把派生类中父类那部分切来赋值过去。

当派生类对象直接赋值给基类对象时,会发生“切片”——派生类独有的成员被丢弃:


四、继承中的作用域

4.1、隐藏

子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏, 也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)

比如:


五、派生类中的成员函数

5.1、构造与析构

1. 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。

2. 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。如下:

可以看到:派生类对象初始化先调用基类构造再调派生类构造。派生类对象析构清理先调用派生类析构再调基类的析构

注意:虽然这里的子类和父类析构名不同,也没加virtual,看起来不构成隐藏。实际上由于多态的原因析构函数的函数名被特殊处理了,统一处理成destructor。

另外:

3. 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。

4. 派生类的operator=必须要调用基类的operator=完成基类的复制。


六、继承与友元、静态成员

6.1、友元关系不可继承

基类的友元函数/类不会自动成为派生类的友元。

class Base 
{friend void friendFunc();
};class Derived : public Base 
{// friendFunc() 不是Derived的友元!
};

6.2、静态成员共享

基类的静态成员在整个继承体系中共享。

class Base 
{
public:static int count;
};class Derived : public Base {};int Base::count = 0;// 无论通过Base还是Derived访问,count都是同一个
Base::count++;
Derived::count++; 

七、复杂的菱形继承与虚拟继承

7.1、菱形继承问题

当派生类继承自两个具有共同基类的类时,会导致数据冗余和二义性:在Assistant的对象中Person成员会有两份。

class Person
{
public :string _name ; // 姓名
};class Student : public Person{};class Teacher : public Person{};class Assistant : public Student, public Teacher
{
protected :string _majorCourse ; // 主修课程
};void Test ()
{Assistant a ;// 这样会有二义性无法明确知道访问的是哪一个a._name = "peter"; // 这里的_name指的是Student里的还是Teacher里的?
}

7.2、虚拟继承

虚拟继承可以解决菱形继承的二义性和数据冗余的问题。

class Person
{
public:string _name; // 姓名
};class Student : virtual public Person {};class Teacher : virtual public Person {};class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};void Test()
{Assistant a;a._name = "peter"; //指向唯一的_name
}

7.2.1、解决原理

这里以下面举例:

class A
{
public:int _a;
};class B : virtual public A
{
public:int _b;
};class C : virtual public A
{
public:int _c;
};class D : public B, public C
{
public:int _d;
};
int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}

图上用的32位系统展示,所以指针大小4个字节。

原理:通过虚拟继承,D对象仅包含一份A实例,B和C共享这一份。这里是通过了B和C的两个指针,指向的一张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到下面的A。


八、继承与组合:如何选择?

public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。

组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象

1. 继承("is-a"关系)

  • 适用场景:派生类是基类的特殊类型(如 Dog 是 Animal)。

  • 优点:代码复用、多态支持。

  • 缺点:可能导致紧耦合。

2. 组合("has-a"关系)

  • 适用场景:类包含另一个类的功能(如 Car 有一个 Engine)。

  • 优点:降低耦合、灵活替换组件

class Engine 
{
public:void start() { /* ... */ }
};class Car 
{
private:Engine engine;  // 组合
public:void start() { engine.start(); }
};

3. 选择原则

  • 优先使用组合:除非需要多态或严格的“is-a”关系。

  • 避免过度继承:继承层次过深会增加复杂度。

http://www.dtcms.com/wzjs/14725.html

相关文章:

  • 可以做样机图的网站短视频营销成功案例
  • 企业网站设计一般多少钱企业网站推广的一般策略
  • 现在有哪些网站是做批发的网络营销的方式有十种
  • 网络运营需要什么学历惠州关键词排名优化
  • wordpress 无法加载css深圳seo优化排名优化
  • 附近室内设计培训学校南京seo招聘
  • WordPress改造成mipseo标题优化关键词
  • 门户网站制作平台江苏网站建站系统哪家好
  • 哪家网站建设服务好新闻内容摘抄
  • 买了个网站后怎么做的nba季后赛最新排名
  • 寺庙招人做网站维护吗公众号推广引流
  • 优良的定制网站建设武汉网站seo
  • 西安网站制作工作室seo优化的主要任务包括
  • 东莞网页制作招聘信息百度seo简爱
  • 最新网站建设方案最有效的广告宣传方式
  • 网站的外部链接怎么做品牌策划方案模板
  • 横峰网站建设汕头seo网站建设
  • 帝国做网站互联网
  • wordpress ip_hash失效常用的seo查询工具
  • 鹏达建设集团有限公司网站360seo关键词优化
  • 专业的河南网站建设怎么优化网站关键词的方法
  • 网站的建设分析关键词排名查询工具
  • 网站静态和动态区别是什么代写平台
  • 甘肃省5g网站建设中标单位网络推广员要怎么做
  • 政务公开与网站建设网站优化系统
  • 做网站费用怎么核算此网站不支持下载视频怎么办
  • 做公司网站写什么信息前端培训哪个机构靠谱
  • 网站域名商代理商淘宝seo关键词的获取方法有哪些
  • 微信链接网站怎么做的seo兼职
  • 做游戏模板下载网站有哪些宁德市人力资源和社会保障局