首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

EasyC++79,虚函数注意事项

这里简单做一个总结: 在方法声明中使用关键字virtual可以声明虚函数 加上了virtual关键字函数以及派生和派生再派生出来中都是虚 在调用虚函数时,程序将会根据对象类型执行对应方法而非引用或指针类型...构造函数 构造函数不能是虚函数,创建派生对象时将调用派生构造函数,而非构造函数,毕竟构造函数是根据名调用。...没有重新定义 如果派生当中没有重新定义虚函数,那么将使用函数版本。如果派生位于派生链中,如B继承了A,C继承了B这种情况,那么派生将会使用最新函数版本。...speak,而在子类Human当中也定义了一个需要传入一个string类型函数speak。...在派生当中重新定义函数,不是使用相同函数特征标覆盖声明,而是隐藏同名方法,不管函数特征标如何。

21410

C++继承

调试发现,学生和教师创建对象中有信息成员和成员函数。 定义 这里来说说定义格式: 派生也可以叫子类也可以叫做父。...构造函数: 首先要知道,在子类当中,父成员要调用父构造函数才能初始化,这里父构造函数我们用缺省值,如果将缺省值去掉,还是像这样去创建子类对象是会报错。...那么如果子类想写构造函数,初始化父成员函数必须去调用父构造函数,不然会报错。...如果没有默认构造函数,则必须在派生构造函数初始化列表阶段显示调用。 拷贝构造: 因为都是内置类型,如果子类成员就调用子类默认拷贝构造,父成员就去调用父拷贝构造。...那么如果遇到深拷贝时候,子类就必须去写构造函数了。 在初始化列表中调用父拷贝构造就可以了。 派生拷贝构造函数必须调用拷贝构造完成拷贝初始化。

43810
您找到你想要的搜索结果了吗?
是的
没有找到

C++ 一篇搞懂继承常见特性

— 1 — 继承和派生 || 01 继承和派生概念 继承: 在定义一个 B 时,如果该类与某个已有的 A 相似(指的是 B 拥有 A 全部特点),那么就可以把 A 作为一个,而把B作为一个派生...空间上讲,用指针可以节省空间,免于构造 B 对象,而是在对象中开辟了一个指针,而不是开辟了一个对象 B 大小。 效率上讲,使用指针适合复用。...---- — 3 — 派生覆盖其他成员 派生子类)可以定义一个(父)成员同名成员,这叫「覆盖」。 在派生子类)中访问这类成员时,默认情况是访问派生中定义成员。...---- — 5 — 派生构造函数 通常在初始化派生构造函数时,派生构造函数是要实现初始化构造函数。...第33-36行代码是正确派生构造函数初始化构造函数方式,通过调用构造函数来初始化,在执行一个派生构造函数 之前,总是先执行构造函数

57230

函数

3、 必须先使用指针指向子类对象,然后直接或者间接使用指针调用虚函数。   ...而不将析构函数定义为虚函数时,调用析构函数。   (2)只需要在声明函数体中使用关键字“virtual”将函数声明为虚函数,而定义函数时不需要使用关键字“virtual”。   ...下面,我们来看一下,如果子类中有函数重载了父函数,会是一个什么样子?假设,我们有下面这样一个继承关系。   ...为了让大家看到被继承过后效果,在这个设计中,覆盖了父一个函数:f()。...虽然在上面的图中我们可以看到子类虚表中有Derive自己函数,但我们根本不可能使用指针来调用子类自有虚函数:   Base1 *b1 = new Derive();   b1->f1();

78431

编译器角度看C++复制构造函数

如果我们数据成员都是内置类型而没有指针,那么简单浅拷贝是可以接受,反之如果中有需要深层复制内容,则我们复制构造函数必须以深拷贝方式进行对象复制。...当继承于一个而后者有已给复制构造函数时(同样,无论构造函数是设计者明确声明还是合成)。 当声明了一个或多个虚函数时。 当派生自一个继承串链,其中有一个或多个虚时。...前两种情况中,编译器必须将“成员或复制构造函数调用操作”安插到新合成复制构造函数中去,如果类设计者已经明确声明了一个复制构造函数,则这些调用操作代码将插入到已有的复制构造函数中去(在函数最前端插入...而对于第4点涉及到虚情况,可以看C++合成默认构造函数真相中有关虚描述。...虚存在需要特殊处理,一个对象如果以另一个对象作为初值,而后者派生于虚,那么这种情况下bitwise copy语意也会失效,编译器会对派生自虚合成一个默认构造函数,在其中安插一些操作。

58070

【C++】继承

继承中作用域 在继承体系中和派生都有独立作用域。 子类和父中有同名成员,子类成员将屏蔽父对同名成员直接访问,这种情况叫隐藏,也叫重定义。...(在子类成员函数中,可以使用 ::成员 显示访问) 需要注意如果是成员函数隐藏,只需要函数名相同就构成隐藏。...派生构造函数必须调用构造函数初始化那一部分成员。如果没有默认构造函数,则必须在派生构造函数初始化列表阶段显示调用。...,子类中会把父成员当做一个整体,在子类不写构造时,会调父默认构造。...赋值构造 如果没有指明作用域,它和父是同名函数,会构成隐藏,优先调用自己,就会死循环。

9710

【C++】继承

所以什么时候可以把成员定义成私有啊,除了不想在外被访问到: ,是不是如果当前某些成员不想被子类使用和访问,也可以把它定义成私有啊。...3.2 隐藏/重定义 那在继承体系中,如果出现这种情况,即子类和父中有同名成员,它有一个专属称谓 子类和父中有同名成员,子类成员将屏蔽对父类同名成员直接访问(默认访问到子类一个),这种情况叫隐藏...(在子类成员函数中,可以使用 ::成员 显示访问)。 我们继续,刚才是子类和父中出现同名成员变量,那如果是出现同名成员函数呢?...而我们Student里面只定义了一个成员变量_num,其它啥也没写。 但我们看到s自动去调用了它父构造和析构。 那如果子类对象自己显示实现构造函数呢?...如果没有默认构造函数,则必须在派生构造函数初始化列表阶段显示调用。 那其实这里感觉就有点像子类里面有一个自定义类型成员一样。

11210

C++-带你初步走进继承(1)

子类和父中有同名成员, 子类成员将屏蔽父对同名成员直接访问,这种情况叫隐藏, 也叫重定义。 (在子类成员函数中,可以 使用 :: 成员 显示访问 ) 3....因为两个作用域是独立,而构成重载前提是同一作用域。 如果出现和派生定义了同名成员,可以使用使用 ::成员 显示访问。...派生构造函数必须调用构造函数初始化那一部分成员。如果没有默认 构造函数,则必须在派生构造函数初始化列表阶段显示调用。 2....当我自己写了一个Student构造函数,那么怎么初始化成员呢?可以在初始化列表调用构造函数,然后我们可以看到,是先调用了构造函数,再构造派生成员。...那么拷贝构造和赋值重载怎么构造呢?也是差不多使用构造函数完成对成员构造,然后使用赋值切片,把成员切过去构造。 那析构函数呢?

11510

【C++】多态

函数重写(也可以叫覆盖): 派生中有一个完全相同函数(即派生函数函数返回值类型、函数名字、参数列表完全相同),称子类函数重写了函数。...但是在这个地方,我们期望它是这样正常调父析构吗? 是不是不期望啊,因为如果指针指向子类对象,在delete时候还是调父析构,那是不是就可能会有内存泄漏风险啊。...那现在大家思考一个问题,test函数里面调用func,是否构成多态? 那我们就看它是否满足多态两个条件嘛,首先虚函数重写,这里是满足子类对父函数func进行了重写。...5.2 override 然后再看一个关键字叫做override 他有什么作用呢? override:检查派生是否函数进行了重写,如果没有重写编译报错。...举个例子来说明抽象概念: 假设我们有一个抽象叫做"动物",其中有一个纯虚函数"发出声音"。我们知道每种动物都会发出声音,但是具体声音是不同

10010

继承

中,如果没有默认成员函数,我们必须在派生中显示写出。...如果中有默认成员函数,当派生中不显示调用时候,会自动调用。 对于构造函数,都会在初始化列表时候自动调用构造函数。...这样才能保证先析构派生,再析构 构造函数 1.当有默认构造函数时候,可以初始化派生成员变量,也可以自己调用默认构造,看自己心情。...2.当没有默认构造函数时候,必须自己要写构造函数调用 派生构造函数先初始化,再初始派生成员 静态成员变量不属于具体对象,属于该类所有对象。...,那么上面的代码就会报错 此时B就应该在初始化列表显示调用A中构造函数

23840

python学习32(面向对象_3)

(200)#子类调用父方法 c1.getAttr()#子类调用父方法 在子类中调用方法 .method(self) 如果子类没有定义构造方法,实例化子类对象时候会调用构造方法...注意: 两次参数列表中self参数都是必不可少如果构造方法中有除了self参数外别的参数,调用时,也必须传入同等数量、同等类型参数。...当子类不定义自己构造方法时,默认会自动调用父构造方法。Python中super函数只能在构造方法中使用。...(默认调用第一个构造方法) ➢如果子类重新定义了自己构造方法,就不会调用父构造方法。...__init__(self, [parameter1[,parameter2....]] ) ➢如果中有同名方法时,通过子类实例对象去调用该方法也是第一个方法。

35610

Python中声明,使用,属性,实例

__init__函数:类似于java中构造函数,以及使用 实例如下: #eg:定义一个 class Dog: def __init__(self):   #方法名为 __init...__ 形参必须要带一个self 当然也可以别名 self习惯使然 print("是一小狗") #创建一个实例 dog_1 = Dog()           #创建实例,也就是调用这个...输出结果如下: 是一小狗 当一个实例被创建出来时候__init__(self)方法就会被自动调用,类似于java,C#中构造函数。...替代 """ 下面定义两个父在(父中创建一个实例函数)和一个子类 子类继承父: class father: def __init__(self): print("是父亲...实例函数,可见当子类继承了父之后, 子类也会继承父函数,包括实例函数,但是只会继承第一个函数 方法重写: 当子类继承了父函数之后,函数子类需要,但是函数体又不是子类需要

5.5K21

Google C++ 编程风格指南(三):

如果中有成员变量没有在里面进行初始化, 而且没有提供其它构造函数, 你必须定义一个 (不带参数) 默认构造函数. 把对象内部状态初始化成一致 / 有效值无疑是更合理方式....如果派生相比引入了新成员变量, 继承构造函数就会让人迷惑, 因为并不知道这些新成员变量存在. 结论: 在能够减少冗余代码, 提高可读性前提下使用委派和继承构造函数....如果使用继承的话, 定义为 public 继承. 定义: 当子类继承时, 子类包含了父所有数据及操作定义....多重继承 真正需要用到多重实现继承情况少之又少. 在以下情况我们才允许多重继承: 最多只有一个是非抽象; 其它都是以 Interface 为后缀 纯接口....> 接口继承 > 私有继承, 子类重载函数也要声明 virtual 关键字, 虽然编译器允许不这样做; 避免使用多重继承, 使用时, 除一个含有实现外, 其他均为纯接口; 接口名以 Interface

79240

c++和继承面试点25连问

2. c++继承优点和缺点 优点:根据第1点中讲,其实继承优点就是实现了代码重用和接口重用; 缺点:子类会继承父部分行为,父任何改变都可能影响子类行为,也就是说,如果继承下来实现不适合子类问题...运行时多态简单来讲就是:使用指针或者引用指向一个派生对象,在非虚继承情况下,派生直接继承虚表指针,然后使用派生函数去覆盖函数,这样派生对象通过虚表指针访问到函数就是派生函数了...,但是函数没有virtual关键字,此时,函数将被隐藏; 总结:函数名相同,参数也相同情况下,如果函数有virtual关键字,则是多态,否则就是隐藏;函数名相同,参数不同情况下,如果函数位于同一个中...一个原则:当中有很少方法并且有公有数据时,应该使用struct关键字,否则使用class关键字。 15....由成员变量和是否有虚函数决定,如果中有函数,那就在所有成员变量基础上加上一个函数指针大小,在64位机器中,虚函数指针为8个字节,注意计算大小时候要考虑字节对齐问题。

91910

继承

,想访问被隐藏成员,可以借助作用域限定符“::” 子类对象任何时候都可以被当成类型对象(皆然性 ISA) 保护继承特点 使公有成员和保护成员进行保护化,禁止外部通过该子类访问 子类指针或引用不能隐式转换成类型指针或引用...() { //son s; 无法实例化对象 } 构造析构顺序 子类构造 子类构造函数会调用构造函数构造子类对象中子对象 子类构造函数没有显示指明基构造方式,会选择缺省构造函数...(无参构造) 子类显示调用构造函数可以在初始化表中显示指明构造方式。...构造顺序 在构造析构里面分析过 * 为整个对象分配内存 * 构造部分(如果存在) * 构造成员变量 * 执行构造函数代码 */ //无参构造 //Student s1; //单参构造...Student s1(18); cin.get(); return 0; } 多继承 一个可以从多个继承 多重继承内存布局 子类对象中子对象按照继承表顺序依次构造 #include

67820

C++继承特性详解

继承定义: 设想一下,如果我们设计一个学校教务系统,那我们对象就会有学生,老师,辅导员,导员等,当然我们可以使用把他们信息一个一个存起来,像下面这样: 可以发现,学生,老师,辅导员,导员等...子类和父中有同名成员,子类成员将屏蔽父对同名成员直接访问,这种情况叫隐藏, 也叫重定义。(在子类成员函数中,可以使用 ::成员 显示访问) 3....当然有,如下图: 派生默认成员函数: 之前在C++和对象中篇时,讲过了6个默认成员函数: 1. 派生构造函数必须调用构造函数初始化那一部分成员。...如果没有默认 构造函数,则必须在派生构造函数初始化列表阶段显示调用。 2. 派生拷贝构造函数必须调用拷贝构造完成拷贝初始化。 3....也就是说每个派生对象都是一个对象。 2.组合是一种has-a关系。假设B组合了A,每个B对象中都有一个A对象。 3.优先使用对象组合,而不是继承 。

15310

C++终结

由于任何派生对象在创建时候,都必需在派生构造函数中调用父构造函数。所以,只要构造函数子类中无法被访问,那么就阻止了该类被继承,实现终结。...如果一个构造函数声明为私有(private),可以阻止该类进一步派生,但是该类也无法直接实例化了,此方法行不通。注意,构造函数为private,无法直接实例化,但是可以被间接实例化。...一个如果被虚拟继承,那么在创建它子类对象时,该构造函数需要单独被调用。此时,如果构造函数在孙子类构造函数中无法访问,那么就实现了子类不能被继承。...将它默认构造函数访问权限设定为protected,这样它自身不能产生任何实例,只能用作。...一个使用FinalParent实现终结例子如下: #include using namespace std; class FinalParent { protected:

51020

C++实现不能被继承——终结

所以,只要构造函数子类中无法被访问,那么就阻止了该类被继承,实现终结如果一个构造函数声明为私有(private),可以阻止该类进一步派生,但是该类也无法直接实例化了,此方法行不通。...注意,构造函数为private,无法直接实例化,但是可以被间接实例化。间接实例化方法是:中定义一个公有的静态成员函数,由这个函数来完成对象初始化工作。...一个如果被虚拟继承,那么在创建它子类对象时,该构造函数需要单独被调用。此时,如果构造函数在孙子类构造函数中无法访问,那么就实现了子类不能被继承。...将它默认构造函数访问权限设定为protected,这样它自身不能产生任何实例,只能用作。...一个使用FinalParent实现终结例子如下: #include using namespace std; class FinalParent { protected:

1.7K20

C++继承分析

,以及一个对应派生,在派生函数中,调用和成员m_nParent,我们没有在派生中定义这个变量,很明显这个变量来自于子类会继承函数成员和数据成员,下面的汇编代码展示了它是如何存储以及如何调用函数...当父中含有构造函数,而子类中没有时,编译器会提供默认构造函数,这个构造调用父构造,而不做其他多余操作,但是如果子类构造,而父中没有构造,则不会为父提供默认构造。...在子类中将父成员放到内存前段是为了方便子类调用父成员。但是当子类中有对应函数,这个时候会直接调用子类函数,这个时候发生了覆盖。...通过上面的分析可以知道,在派生如果重写了函数,那么在创建新对象时会有两次虚表指针初始化操作,第一次是将虚表指针赋值给对象,然后再将自身虚表指针赋值给对象,将前一次覆盖,如果是在构造中调用虚函数...通过上面的代码可以看出,为了使得相同内容只有一份,在程序中额外传入一个参数作为标记,用于表示是否调用祖父构造函数,当初始化完祖父后将此标记置0以后不再初始化,另外程序在每个父中都多添加了一个四字节成员用来存储一个一个偏移地址

51330
领券