实例代码讲解c++ 继承特性

——派生类需要自己的构造函数。

派生类中可以根据需要添加额外的数据成员和成员函数,甚至可以给予继承的原成员函数新的定义。

   基类指针或引用可指向派生对象,反过来则只能使用强制类型转换。

   派生类对象可使用基类的非私有成员。

   可使用派生对象初始化基类对象或赋值。

   一般不允许将基类对象赋给派生类对象(上面第三条),特殊情况下可以。

   已有派生类对象初始化创建的派生类对象。

   已有派生类对象给另一个派生类对象赋值。

   派生类对象的析构函数被调用后会自动调用基类的析构函数。

   C++11增加了允许继承构造函数的机制,但派生类默认不能继承构造函数和析构函数。

class RatedPlayer : public TableTennisPlayer
 {
 private:
 unsigned int rating; // add a data member
 public:
 RatedPlayer (unsigned int r = 0, const string &fn = "none", const string &ln = "none", bool ht = false);
 RatedPlayer (unsigned int r, const TableTennisPlayer &tp);
 unsigned int Rating() const { return rating; } // add a method
 void ResetRating (unsigned int r) { rating = r; } // add a method
};

构造函数必须给新成员和继承的成员提供数据。

RatedPlayer::RatedPlayer(unsigned int r, const string &fn, const string &ln, bool ht) : TableTennisPlayer(fn, ln, ht)
{
 rating = r;
}
  • 派生类构造函数必须使用基类构造函数,创建派生类对象时,程序首先创建基类对象(初始化继承的数据成员)然后再调用派生类构造函数。C++使用成员初始化列表语法完成该操作。
  • 如没有调用基类构造函数,那么将隐式调用基类的默认构造函数。除非要使用默认构造函数,否则应显示调用正确的基类构造函数。

派生类对象过期时,程序将首先调用派生类析构函数,然后再自动调用基类析构函数。

要使用派生类,程序必须要能访问基类声明。

派生类对象可以使用基类的方法,条件是方法不是私有的(即公有和保护)。

基类指针可以在不进行显示类型转换的情况下指向派生类对象;基类引用可以在不进行显示类型转换的情况下引用派生类对象

RatedPlayer rplayer(1140, "Mallory", "Duck", true);
TableTennisPlayer &rt = rplayer;
TableTennisPlayer *pt =&rplayer;
rt.Name(); // invoke Name() with reference
pt->Name(); // invoke Name() with pointer

不可以将基类对象和地址赋给派生类引用和指针,除非使用强制转换(友元函数不是成员函数因此不能被继承,但欲使用基类的友元函数时可使用此方法,但要小心用错)。

基类声明的函数引用参数或指针参数可用于值为基类对象或派生类对象以及它们的地址的情况。

void Show(const TableTennisPlayer &rt)
{
 ...
}
TableTennisPlayer player1("Tara", "Boomdea", false);
RatedPlayer rplayer1(1140, "Mallory", "Duck", true);
Show(player1); // works with TableTennisPlayer argument
Show(rplayer1); // works with RatedPlayer argument

省略形参为const TableTennisPlayer *rt的情况,与上相似。

引用兼容性属性:可以将基类对象初始化为派生类对象。

RatedPlayer olaf1(1840, "Olaf", "Loaf", true);
TableTennisPlayer olaf2(olaf1);

匹配的构造函数的原型:

TableTennisPlayer(const RatedPlayer &); // doesn't exit

类中并没有该构造函数,但存在隐式复制构造函数:

// implicit copy constructor
TableTennisPlayer(const TableTennisPlayer &);

即它将olaf2初始化为嵌套在RatedPlayer对象olaf1中的TableTennisPlayer对象(使用派生类中嵌套的基类对象对目标基类对象进行初始化)

同样,也可以将派生对象赋给基类对象:

RatedPlayer olaf1(1840, "Olaf", "Loaf", true);
TableTennisPlayer winner;
winner = olaf1; // assign derived to base object

在这种情况下,程序使用隐式重载赋值运算符:

TableTennisPlayer &operator=(const TableTennisPlayer &) const;

与上类似,使用派生类中嵌套的基类对象对目标基类对象进行按成员赋值。

特殊的用基类对象给派生类对象赋值的情况

如果派生类包含了将基类对象转换为派生类对象的构造函数,或派生类定义了将基类对象赋给派生类对象的赋值运算符,则可以用派生类对象给基类对象赋值。

用已有的派生类对象初始化创建的派生类对象

复制类成员或继承的类组件时,则是使用该类的复制构造函数完成的,对于继承的基类对象来说也是合适的。

用已有的派生类对象给另一个派生类对象赋值

按成员赋值,调用类成员赋值运算符,使用基类的赋值运算符来对基类组件(继承的基类对象)进行赋值

若派生类使用了动态内存分配,派生类的析构函数、复制构造函数、复制运算符都必须使用相应的基类方法来处理基类元素(显示调用基类构造函数和复制运算符):

  • 对于析构函数,这是自动完成的。
  • 对于复制构造函数,这是在初始化成员列表中调用基类的复制构造函数来完成的;如果不这么做,将自动调用基类的默认构造函数。
  • 对于复制运算符,这是通过使用作用域解析运算符显示地调用基类的赋值运算符来完成的:
hasDMA &hasDMA::operator=(const hasDMA &has)
{
 if (this == &hs)
 return *this;
 baseDMA::operator=(hs); // copy base portion
 ...
 return *this;
}

以上就是实例代码讲解c++ 继承特性的详细内容,更多关于c++ 继承特性的资料请关注我们其它相关文章!

(0)

相关推荐

  • C++类继承之子类调用父类的构造函数的实例详解

    C++类继承之子类调用父类的构造函数的实例详解 父类HttpUtil: #pragma once #include <windows.h> #include <string> using namespace std; class HttpUtil { private: LPVOID hInternet; LPVOID hConnect; LPVOID hRequest; protected: wchar_t * mHostName; short mPort; string send

  • C++多重继承及多态性原理实例详解

    一.多重继承的二义性问题 举例: #include <iostream> using namespace std; class BaseA { public: void fun() { cout << "A.fun" << endl; } }; class BaseB { public: void fun() { cout << "B.fun" << endl; } void tun() { cout &l

  • C++类继承 继承后函数的值实现详解

    类的继承会首先寻找基类,若基类未实现,则会寻找派生类的函数 1. class继承,函数不继承 #include <stdio.h> class Base { public: Base(){} ~Base(){} int a; void setA() { a = 1; } }; class A:public Base { public: A(){} ~A(){} void setA() { a = 2; } }; class B:public Base { public: B(){} ~B(){

  • C++中的封装、继承、多态理解

    封装(encapsulation):就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成"类",其中数据和函数都是类的成员.封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,特定的访问权限来使用类的成员.封装可以隐藏实现细节,使得代码模块化. 继承(inheritance):C++通过类派生机制来支持继承.被继承的类型称为基类或超类,新产生的类为派生类或子类.保持已有类的特性而构造新类的过

  • 详解c++ 继承

    面向对象程序设计中最重要的一个概念是继承.继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得更容易.这样做,也达到了重用代码功能和提高执行效率的效果. 当创建一个类时,您不需要重新编写新的数据成员和成员函数,只需指定新建的类继承了一个已有的类的成员即可.这个已有的类称为基类,新建的类称为派生类. 继承代表了 is a 关系.例如,哺乳动物是动物,狗是哺乳动物,因此,狗是动物,等等. 基类 & 派生类 一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数.定义一个派

  • C++中的多态与多重继承实现与Java的区别

    多态问题 笔者校招面试时被问到了著名问题「C++ 与 Java 如何实现多态」,然后不幸翻车.过于著名反而没有去准备,只知道跟虚函数表有关.面试之后比较了 C++ 和 Java 多态的实现的异同,一并记录在这里. C++ 多态的虚指针实现 首先讨论 C++. 多态也即子类对父类成员函数进行了重写 (Override) 后,将一个子类指针赋值给父类,再对这个父类指针调用成员函数,会调用子类重写版本的成员函数.简单的例子: class Parent1 { public: virtual void s

  • C++多重继承二义性原理实例解析

    在派生类中对基类成员访问应该是唯一的,但是在多继承时,可能会导致对基类某成员访问出现不一致的情况,这就是C++多继承中的二义性. 有两种继承的情况会产生多义性 一.如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的成员变量进行访问时,可能产生二义性,继承关系如下图所示: #include <iostream> using namespace std; class A{ public: int a; }; class B1 : public A{ public: i

  • 实例代码讲解c++ 继承特性

    --派生类需要自己的构造函数. 派生类中可以根据需要添加额外的数据成员和成员函数,甚至可以给予继承的原成员函数新的定义. 基类指针或引用可指向派生对象,反过来则只能使用强制类型转换. 派生类对象可使用基类的非私有成员. 可使用派生对象初始化基类对象或赋值. 一般不允许将基类对象赋给派生类对象(上面第三条),特殊情况下可以. 已有派生类对象初始化创建的派生类对象. 已有派生类对象给另一个派生类对象赋值. 派生类对象的析构函数被调用后会自动调用基类的析构函数. C++11增加了允许继承构造函数的机制

  • Android Dialog对话框实例代码讲解

    Dialog的基本方法 //创建Dialog AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); //设置标题图标 builder.setIcon(R.drawable.ic_launcher); //设置标题 builder.setTitle("这是一个对话框"); //设置信息 builder.setMessage("是否要跳转?"); //确定按钮 setPosit

  • 实例代码讲解JAVA多线程

    进程与线程 进程是程序的一次动态执行过程,它需要经历从代码加载,代码执行到执行完毕的一个完整的过程,这个过程也是进程本身从产生,发展到最终消亡的过程.多进程操作系统能同时达运行多个进程(程序),由于 CPU 具备分时机制,所以每个进程都能循环获得自己的CPU 时间片.由于 CPU 执行速度非常快,使得所有程序好像是在同时运行一样. 多线程是实现并发机制的一种有效手段.进程和线程一样,都是实现并发的一个基本单位.线程是比进程更小的执行单位,线程是进程的基础之上进行进一步的划分.所谓多线程是指一个进

  • ASP.NET操作MySql数据库的实例代码讲解

    一.把MySql.Data.dll放到BIN目录下. 二.这是aspx.cs的全部源码,修改参数直接运行即可!   using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; publ

  • jQuery判断邮箱格式对错实例代码讲解

    废话不多说了,具体代码如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>检测Email地址格式是否正确</title> <script src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"><

  • JS实现JSON.stringify的实例代码讲解

    JSON.stringify是浏览器高版本带的一个将JS的Objtect对象转换为JSON字符串的一个方法,不过再IE6下面,并不存在JSON这一对象,因此,用到此方法时,需要写一套兼容性的代码. JSON.stringify的一些规则以及注意点:当对象为数字,null,boolean的时候,直接转换为相应的字符串就可以了. 但是string,function,undefined,object,array等,需要特殊处理. 1.undefined,该类型使用JSON.stringify处理的时候

  • Spring boot + mybatis + orcale实现步骤实例代码讲解

    接着上次的实现, 添加 mybatis 查询 orcale 数据库 第一步: 新建几个必须的包, 结果如下 第二步: 在service包下新建personService.java 根据名字查person方法接口 package com.example.first.service; import com.example.first.entity.Person; public interface personService { Person queryPersonByName(String name

  • vue slot与传参实例代码讲解

    插槽分为默认插槽和具名插槽: 默认插槽: //父组件 <div> <h3>父组件</h3> <testChild> <div>默认插槽</div> </testChild> </div> //子组件 <div> <h4>子组件</h4> <slot></slot> </div> 具名插槽: 注意:具名插槽需要包裹在  template  标

  • 实例代码讲解JAVA 观察者模式

    当对象间存在一对多关系时,则使用观察者模式(Observer Pattern).比如,当一个对象被修改时,则会自动通知依赖它的对象.观察者模式属于行为型模式. 介绍 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作. 何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知. 如何解决:使用面向对象技术

  • 实例代码讲解c# 线程(下)

    前言 实例代码讲解c# 线程(上) 使用Mutex类 class Program { static void Main(string[] args) { const string MutexName ="CSharpThreadingCookbook"; using (var m = new Mutex(false, MutexName)) { if (!m.WaitOne(TimeSpan.FromSeconds(5), false)) { Console.WriteLine(&qu

随机推荐