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

南宁网站建设建站系统学营销app哪个更好

南宁网站建设建站系统,学营销app哪个更好,谷歌怎么做网站推广,网站建设价格很 好乐云seo目录 一、继承概念与定义 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/523285.html

相关文章:

  • 泰兴市 建设安全监察网站seo关键词大搜
  • 南京专业做网站公司站外seo推广
  • 网站文章内容排版要求网络服务运营商
  • 网站欢迎页面flash关键词英文
  • 武汉专业手机网站建设如何自己做一个网址
  • 定制衣柜哪种板材最好长沙官网网站推广优化
  • 网站制作厦门公司淘宝培训
  • 那些是flash做的网站百度首页清爽版
  • 免费源码资源源码站入口杭州关键词优化外包
  • 用javascript做的网站b站是哪个网站
  • 织梦如何做网站留言功能河北网站建设推广
  • 福建两学一做网站重庆seo网络优化师
  • 网站开发情况兰州网站seo
  • 独立页面成网站通过如何创建自己的小程序
  • h5开网站开发教程it培训机构哪个好一点
  • 沈阳中小企业网站制作北京百度推广代运营
  • 画江湖网站开发文档关键词的优化方案
  • 建设软件资源网站seo站长网怎么下载
  • 响应式网站设计原理sem工作内容
  • 淮南做网站的公司销售网站有哪些
  • 上海市住房和城乡建设厅官方网站网络优化的工作内容
  • 别人帮我做的网站没用要交费用吗黄金网站软件app大全下载
  • 做手机网站一般要多少钱企业管理培训课程视频
  • 兰州网站开发在哪里网页设计页面
  • 网站开发心得体会南宁百度seo价格
  • 公司部门划分及职责余姚网站seo运营
  • 生意宝做网站行吗电商运营培训班多少钱
  • 家庭宽带怎么做网站网络营销就是
  • 传统网站开发中国足彩网竞彩推荐
  • asp网站制作教程爱站工具包手机版