派生类

C++纯虚函数

不问归期 提交于 2019-12-07 06:55:29
在成员函数的形参后面写上=0,则成员函数为纯虚函数。 纯虚函数声明: virtual 函数类型 函数名 (参数表列) = 0; class Person { virtual void Display () = 0 ; // 纯虚函数 protected : string _name ; // 姓名 }; class Student : public Person {}; 注意: (1)纯虚函数没有函数体; (2)最后面的“=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是虚函数”; (3)这是一个声明语句,最后有分号。 纯虚函数只有函数的名字而不具备函数的功能,不能被调用。 纯虚函数的作用是在基类中为其派生类保留一个函数的名字,以便派生类根据需要对他进行定义。如果在基类中没有保留函数名字,则无法实现多态性。 如果在一个类中声明了纯虚函数,在其派生类中没有对其函数进行定义,则该虚函数在派生类中仍然为纯虚函数。 抽象类: 不用定义对象而只作为一种基本类型用作继承的类叫做抽象类(也叫接口类),凡是包含纯虚函数的类都是抽象类,抽象类的作用是作为一个类族的共同基类,为一个类族提供公共接口,抽象类不能实例化出对象。 纯虚函数在派生类中重新定义以后,派生类才能实例化出对象。 总结: 1、派生类重写基类的虚函数实现多态,要求函数名、参数列表、返回值完全相同。(协变除外) 2

c++ 之继承

邮差的信 提交于 2019-12-06 08:45:46
1.继承格式 class Base{ public: Base(); //... } class Derived: public Base //类派生列表 { public: Derived(); //... } 2.总结 1)派生类也从基类中继承私有成员,只是派生类不能访问基类中的私有成员。 2)派生类是由 基类和派生类自己定义的成员 组成,基类部分和派生类部分存储的时候不一定是连续的。 3)派生类和基类都控制着自己的成员初始化,派生类最好通过基类接口去访问基类。 4)将派生类中的基类部分也看作是基类的一个“对象”,这是这个“对象”还可以访问保护成员。 5)继承是派生类在基类上的一个扩展。 //未完待续..... 来源: https://www.cnblogs.com/jiayouya-susu/p/11973618.html

继承设计

荒凉一梦 提交于 2019-12-06 04:59:04
1 .回顾类和对象的创建 定义学生类Student,包含私有数据成员:num(学号)、name(姓名,字符数组)、age(年龄);公有成员函数:Student(构造函数)、~Student(析构函数),使用构造函数为Student类对象的数据成员赋值 (name使用动态内存分配),在析构函数中释放动态分配的内存 ,显示函数display(显示学生信息)。 法一: #include<iostream> #include<string> using namespace std; class Student { private: long num; char* name; int age; public: Student() {} Student(long nu, char* na, int a) :num(nu), name(na), age(a) {} ~Student() {} void display() { cout << "学号:" << num << " " << endl << "姓名:" << name << endl << "年龄:" << age << endl; } }; int main() { char ch[] = "李丽"; Student* ptr = new Student();//① ptr = new Student(3018314, ch, 18

C++ 继承与派生

戏子无情 提交于 2019-12-06 02:47:06
继承:在一个已经存在的类的基础上建立一个新的类,这个新类从已有的的类哪里获得已有的特性 派生类:继承了已有类的全部成员数据和成员函数 继承又有单继承和多重继承的方式 关系:派生类是基类的具体化,基类是派生类的抽象 继承方式 :class 派生类名:继承方式 基类名    //如果不写继承方式则默认为private     {       派生类中新增加的成员;     }; 派生类的构成: 从基类接收成员:接收基类的全部数据成员(不包括构造函数和析构函数)不可选择接收的数据 调整从基类接收的成员:在派生类中可以实现同名覆盖(参数表) 声明派生类新增加的成员 派生类中成员的 访问属性 : 公共继承:基类的公用成员和保护成员在派生类中保持原有访问属性,其私有成员仍为基类私有,不可访问。 私有继承:基类的公用成员和保护成员在派生类中成了派生类的私有成员,其私有成员仍为基类私有。 受保护的继承:基类的公用成员和保护成员在派生类中成了保护成员,其私有成员仍为基类私有。保护成员的意思是,不能被外界引用,但可以被派生类的成员引用。   私有成员在派生类中都成为不可访问的属性,派生类中的一切成员均无法访问它们。 多级派生时的访问属性:直接派生,间接派生 派生类的构造函数和析构函数: 构造函数的主要作用就是对数据成员的初始化。 构造和析构函数是不能被继承的需要 在执行派生类的构造函数时

基于指针构造的程序设计

纵然是瞬间 提交于 2019-12-05 23:57:59
【实验目的】 (1)掌握指针的概念,会定义和使用指针变量 (2)指针与对象结合的使用 1、 程序设计题 :编写函数 fun(char *s),功能是把 s所指字符串中的内容逆置。例如:字符串中原有的字符串为: abcdefg,则调用该函数后 , 串中的内容为: gfedcba #include <string.h> #include <stdio.h> #define N 81 void fun ( char *s ) { int i, j;//写入你的代码 char t; for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { t = s[i]; s[i] = s[j]; s[j] = t; } } void main(void) { char a[N]; printf ( "Enter a string : " ); gets ( a ); printf ( "The original string is : " ); puts( a ); fun ( a ); printf("\n"); printf ( "The string after modified : "); puts ( a ); } 字符串逆置: void fun ( char *s ) { int i, j;//写入你的代码 char t; for (i = 0,

static_cast和dynamic_cast详解

一笑奈何 提交于 2019-12-05 19:13:41
注:从图中可以看出,派生类不仅有自己的方法和属性,同时它还包括从父类继承来的方法和属性。当我们从派生类向基类转换时,不管用传统的c语言还是c++转换方式都可以百分百转换成功。但是可怕是向下转换类型,也就是我们从基类向派生类转换,当我们采用传统的C语言和c++转换时,就会出现意想不到的情况,因为转换后派生类自己的方法和属性丢失了,一旦我们去调用派生类的方法和属性那就糟糕了,这就是对类继承关系和内存分配理解不清晰导致的。好在c++增加了static_cast和dynamic_cast运用于继承关系类间的强制转化 一、static_cast和dynamic_cast使用方式 static_cast< new_type >(expression) dynamic_cast< new_type >(expression) 备注:new_type为目标数据类型,expression为原始数据类型变量或者表达式。 二、static_cast详解: static_cast相当于传统的C语言里的强制转换,该运算符把expression转换为new_type类型,用来强迫隐式转换如non-const对象转为const对象,编译时检查,用于非多态的转换,可以转换指针及其他,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法: ①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。

C# A类派生类强转基类IL居然还是可以调用派生类中方法的例子

拜拜、爱过 提交于 2019-12-05 07:41:15
大家都知道在C#中,如果B类继承自A类,如果一个对象是B类型的但是转换为A类型之后,这个对象是无法在调用属于B类型的方法的,如下例子: 基类A: public class A { } 派生类B: public class B : A { public void Test() { Console.WriteLine("Hello World!"); } } 如果我们这样写: A a = new B(); a.Test(); 我们会发现编译器编译不能通过,有如下的错误: 最近看了一下《C# 从现象到本质》。这本书上写 " 通过IL实现令对象a可以调用B的方法 ",我琢磨了好久才想了一个例子,IL代码如下: .assembly extern mscorlib { auto } .assembly MyTest {} .module MyTest.exe .class public A { .method public specialname void .ctor() { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } } .class public B extends A { .method public specialname void .ctor() { ldarg.0 call instance

015 继承

旧巷老猫 提交于 2019-12-05 05:46:36
/* 派生类与基类 1 派生类的数据大小 (1) 基类 - 结构体 (2) 派生类 - 结构体套结构体 2 顺序问题: (1) 构造与析构: 基类先构造,后析构。派生类,先析构,后构造。 (2) 原因: 依赖关系, 派生类使用基类的数据,所以基类先构造。 3 三种权限: 访问限制 三种地方访问: 本类、派生类、类外 (1) private 本类可以访问 (2) protected: 基类和派生类可以访问 (3) public: 任意地方都可以访问 4 调用 (1) 基类的成员函数无法使用派生类的成员变量和成员函数 (2) 在继承允许的情况下, 派生类可以调用基类的成员变量和成员函数 (a) 允许派生类对基类同名的成员变量和成员函数进行重写 (b) 允许派生类成员函数通过基类名::成员函数/成员变量方式,使用基类的成员变量和成员函数。 (c) 允许派生类对象通过对象名.基类名::成员函数/成员变量方式,使用基类的成员变量和成员函数。 5 赋值 (1) 派生类对象(结构体)可以直接赋值给基类对象(结构体), 反之则不行。 (2) 原因: 派生类对象的数据(成员变量)>=基类对象的数据(成员变量), 反之则是<=。 (1) 派生类对象(指针)可以直接赋值给基类对象(指针), 反之则不行。 (2) 原因: 派生类的数据(成员变量)可以调用基类的成员函数,反之则无法实现。 */ 来源:

c/c++——基本概念

跟風遠走 提交于 2019-12-05 01:01:16
内存 栈区和堆区的管理模式有所不同:栈区内存由系统分配和释放,不受程序员控制;堆区内存完全由程序员掌控,想分配多少就分配多少,想什么时候释放就什么时候释放,非常灵活。 栈(Stack)可以存放函数参数、局部变量、局部数组等作用范围在函数内部的数据,它的用途就是完成函数的调用。 栈区和堆区的内存在程序运行期间可以根据实际需求来分配和释放,不用在程序刚启动时就备足所有内存。这称为动态内存分配。 在栈上创建出来的对象都有一个名字,比如 stu,使用指针指向它不是必须的。但是通过 new 创建出来的对象就不一样了,它在堆上分配内存,没有名字,只能得到一个指向它的指针,所以必须使用一个指针变量来接收这个指针,否则以后再也无法找到这个对象了,更没有办法使用它。也就是说,使用 new 在堆上创建出来的对象是匿名的,没法直接使用,必须要用一个指针指向它,再借助指针来访问它的成员变量或成员函数。 栈内存是程序自动管理的,不能使用 delete 删除在栈上创建的对象;堆内存由程序员管理,对象使用完毕后可以通过 delete 删除。在实际开发中,new 和 delete 往往成对出现,以保证及时删除不再使用的对象,防止无用内存堆积。 有了对象指针后,可以通过箭头 -> 来访问对象的成员变量和成员函数,这和通过 结构体指针 来访问它的成员类似。 成员变量在堆区或栈区分配内存,成员函数在代码区分配内存

类对象定义 二

妖精的绣舞 提交于 2019-12-04 16:27:22
类对象定义 C++类访问修饰符 数据封装是面向对象编程的一个重要特点,它防止函数直接访问类类型的内部成员。类成员的访问限制是通过在类主体内部对各个区域标记 public、private、protected 来指定的。关键字 public、private、protected 称为访问修饰符。 class Base { public: // 公有成员 protected: // 受保护成员 private: // 私有成员 }; 公共(public)成员 公有 成员在程序中类的外部是可访问的。您可以不使用任何成员函数来设置和获取公有变量的值,如下所示: #include <iostream> using namespace std; class Line { public: double length; void setLength( double len ); double getLength( void ); }; // 成员函数定义 double Line::getLength(void) { return length ; } void Line::setLength( double len ) { length = len; } // 程序的主函数 int main( ) { Line line; // 设置长度 line.setLength(6.0); cout <<