基类new一个派生类后delete只调用了基类构造函数,怎么才能调用派生类的构造函数析构

今天看啥 热点:
注:若一个基类同时派生出两个派生类,即两个派生类从同一个基类继承,那么系统将为每一个简历副本,每个派生类独立地使用自己的基类副本(比如基类中有属于自己类的静态变量等)。
class Person
person() {cout<<"Construction of person."<<}
~person() {cout<<"Destruction of person."<<}
class Student:public person
student() {cout<<"Construction of student."<<}
~student() {cout<<"Destruction of student."<<}
class Teacher:public Person
Teacher() {cout<<"Construction of teacher."<<}
~Teacher() {cout<<"Destruction of teacher."<<}
int main()
程序输出:
Construction of person.
Construction of student.
Construction of person.
Construction of teacher.
Destruction of teacher.
Destruction of person.
Destruction of student.
Destruction of person.
结论:若一个程序中有多个对象,每个对象必须按照顺序创建,在创建派生类对象时,调用构造函数的顺序为:基类构造-->子对象构造-->派生类构造。析构函数的调用顺序严&#26684;与构造函数相反。在派生类的构造函数中,当基类的构造函数缺省参数时,在派生类构造函数中可以缺省对基类构造函数的调用。
class Data
Data(int x) {Data::x = cout<<"Data construction."<<}
~Data() {cout<<"Data destruction."<<}
class Base
Base(int x):d1(x) {cout<<"Base construction."<<}
~Base() {cout<<"Base destruction."<<}
class Device:public Base
Device(int x):Base(x), d2(x) //参数共用
{cout<<"Device construction."<<}
~Device() {cout<<"Device destruction."<<}
int main()
Device obj(5);
程序输出:
Data construction.
Base construction.
Data construction.
Device construction.
Device destruction.
Data destruction.
Base destruction.
Data destruction.
构造顺序分析:调用Base类构造,而Base中含有子对象d1,所以要先调用d1的构造函数再调用Base的构造函数;Base构造函数调用完成之后再调用d2的构造;最后一步是调用派生类的构造。
class Base
Base(int xx = 0):x(xx) //注意没有分号,等价于普通的构造函数类型
{cout<<"Base construction."<<} //这个花括号是不能省略的
~Base() {cout<<"Base destrcution."<<}
void print() {cout<<x<<",";}
int Getx() {}
class Device:public Base
Device(itn xx = 0, int yy = 0):Base(xx), y(yy), z(xx&#43;yy)
{cout<<"Device construction."<<}
~Device() {cout<<"Device destruction."<<}
void print()
Base::print();
cout<<y<<","<<z.Getx()<<
int main()
Device obj1(1), obj2(4, 6);
obj1.print();
obj2.print();
程序输出:
Base construction.
Base construction.
Device construction.
Base construction.
Base construction.
Device construction.
析构略......
相关搜索:
相关阅读:
相关频道:
&&&&&&&&&&&&&&&&
C++教程最近更新3621人阅读
名词解释(1)
#include &iostream&
A() { std::cout && &A& && std:: }
virtual ~A() { std::cout && &~A& && std:: }
virtual void Test() { std::cout && &A::Test& && std:: }
B() { std::cout && &B& && std:: }
~B() { std::cout && &~B& && std:: }
class C : public A
C() { std::cout && &C& && std:: }
~C() { std::cout && &~C& && std:: }
void Test() { std::cout &&&C::Test& && std:: }
int main(void)
实例化一个派生类对象:
1.执行基类的构造函数;
2.初始化派生类的成员变量,由于B是一个类类型,所以会调用B的默认构造函数,此时如果B没有默认构造函数会报错;
3.执行派生类的构造函数。
与构造顺序相反
执行结果:
int main(void)
A *pa = new C();
pa-&Test();
构造和析构顺序与上类&#20284;,不过需要注意的是基类A的析构函数必须声明为virtual,否则派生类得不到析构
  虚函数 
  C&#43;&#43;中的虚函数的实现一般是通过虚函数表(C&#43;&#43;规范并没有规定具体用哪种方法,但大部分的厂商都选择此方法)。
  类的虚函数表是一块连续的内存,每个中记录一个JMP指令的地址。
  注意的是,编译器会为每个有虚函数的类创建一个虚函数表,该虚函数表将被该类的所有对象共享。类的每个虚成员占据虚函数表中的一行。如果类中有N个虚函数,那么其虚函数表将有N*4字节的大小。
  虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其真实反应实际的函数。这样,在有虚函数的类的实例中分配了指向这个表的的内存,所以,当用父类的指针来操作一个子类的时候,这张虚函数表就显得尤为重要了,它就像一个地图一样,指明了实际所应该调用的函数。
  编译器应该是保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证取到虚函数表的有最高的性能——如果有多层继承或是的情况下)。 这意味着可以通过对象实例的地址得到这张虚函数表,然后就可以遍历其中,并调用相应的函数。
虚析构函数
  虚析构函数是为了解决这样的一个问题:的指向派生类对象,并用基类的指针删除派生类对象。
  如果某个类不包含,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个,使得对象的体积翻倍,还有可能降低其可移植性。
  所以基本的一条是:无故的声明虚析构函数和永远不去声明一样是错误的。实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。
  是准备被用做基类的,基类必须要有一个虚析构函数,会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。
  这里是一个例子:
  class awov { // awov = &abstract w/o
  // virtuals&
  public:
  virtual ~awov() = 0; // 声明一个纯虚析构函数
  这个类有一个,所以它是抽象的,而且它有一个虚析构函数,所以不会产生析构函数问题。但这里还有一件事:必须提供纯虚析构函数的定义:
  awov::~awov() {} // 纯虚析构函数的定义
  这个定义是必需的,因为虚析构函数工作的方式是:最底层的派生类的析构函数最先被调用,然后各个的析构函数被调用。这就是说,即使是,也要产生对~awov的调用,所以要保证为它提供。如果不这么做,就会检测出来,最后还是得回去把它添上。
  注意:如果声明虚析构函数为inline,将会避免调用它们时产生的开销,但编译器还是必然会在什么地方产生一个此函数的拷贝。
  纯是一种特殊的虚函数,它的一般&#26684;式如下:
  class &类名&
  virtual &类型&&函数名&(&参数表&)=0;
  在许多情况下,在中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的去做。这就是纯虚函数的作用。
  纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义。凡是含有纯虚函数的类叫做。这种类不能声明对象,只是作为基类为派生类服务。除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。
  1、为了方便使用特性,我们常常需要在中定义。
  2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
  为了解决上述问题,引入了纯的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;)。若要使为非,则要求在派生类中,必须对纯虚函数予以重写以实现。同时含有纯虚函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。
  指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C&#43;&#43;支持两种多态性:编译时多态性,。
  a.编译时多态性:通过实现
  b 运行时多态性:通过实现。
  2、虚函数
  虚函数是在中被声明为virtual,并在中重新定义的成员函数,可实现成员函数的动态
  包含纯虚函数的类称为抽象类。由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。
  定义:在某中声明为 virtual 并在一个或多个中被重新定 义的[1]
  语法:virtual 函数返回类型 函数名(参数表) {
  用途:实现,通过指向派生类的基类,访问派生类中同名覆盖成员函数
  虚函数必须是基类的非函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:
  class 基类名{
  .......
  virtual 返回&#20540;类型 将要在派生类中的函数名();
  虚函数的作用是实现,也就是在程序的运行阶段动态地选择合适的,在定义了虚函数后,可以在的中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的个数和形参类型。以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。
  当程序发现虚函数名前的关键字virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数。虚函数是C&#43;&#43;的一种表现。
  例如:子类继承了父类的一个函数(方法),而我们把父类的指向子类,则必须把父类的该函数(方法)设为virtual(虚函数)。
  ([] 注:下行语义容易使人产生理解上的偏差,实际效果应为:
  如存在:Base -& Derive1 -& Derive2 及它们所拥有的虚函数func()
  则在访问派生类Derive1的实例时,使用其基类Base及本身类型Derive1,或被转换的后续派生类Derive2的指针或引用,均可访问到Derive1所实现的func()。)
  动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数,其&#26684;式:
  1、指向基类的指针变量名-&虚函数名(表)
  2、基类对象的引用名. 虚函数名(实参表)
  使用虚函数,我们可以灵活的进行,当然是以一定的开销为代价。如果父类的函数(方法)根本没有必要或者无法实现,完全要依赖子类去实现的话,可以把此函数(方法)设为virtual 函数名=0 我们把这样的函数(方法)称为。
  如果一个类包含了纯虚函数,称此类为。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:17040次
排名:千里之外
原创:40篇
(4)(1)(17)(7)(8)(1)(1)(1)关于c++派生类构造函数和析构函数的说法下列关于派生类构造函数和析构函数的说法中,错误的是:A)派生类的构造函数会隐含调用基类的构造函数B)如果基类中没有缺省构造函数,那么派_百度作业帮
关于c++派生类构造函数和析构函数的说法下列关于派生类构造函数和析构函数的说法中,错误的是:A)派生类的构造函数会隐含调用基类的构造函数B)如果基类中没有缺省构造函数,那么派
关于c++派生类构造函数和析构函数的说法下列关于派生类构造函数和析构函数的说法中,错误的是:A)派生类的构造函数会隐含调用基类的构造函数B)如果基类中没有缺省构造函数,那么派生类必须定义构造函数C)在建立派生类对象时,先调用基类的构造函数,再调用派生类的构造函数D)在销毁派生类对象时,先调用基类的析构函数,再调用派生类的析构函数麻烦把这等方面的内容讲细点
D是错的,应该是在销毁派生类对象时,先调用派生类的析构函数,再调用基类的析构函数.这跟盖房拆房一个道理,盖时肯定要先盖基础(相当于建立时先调用基类),再盖上面(再调用派生类)拆房时,肯定很从上面拆(先调用派生类的析构函数),再拆下面(再调用基类的析构函数)其实上面只有简单的解释,上面的调用是因为,若你先调用基类的析构函数,会把派生类正在用的一次资源销毁,因为此时派生类还没有被销毁,所以肯定会出现问题。如何使派生类对象只调用基类的构造函数_百度知道
如何使派生类对象只调用基类的构造函数
这可以做到么,不调用派生类的构造函数,即达到只对对象的部分数据成员赋值只 调用基类的构造函数
我有更好的答案
果是Java的话,调用的是基类的构造函数;就能在new 派生类的时候.. parameter).,在派生类的构造函数中用super(Object
java版:class Base{
public Base(String name,int age){
this.name =
this.age =
}} class Child extends Base{
public Child(String name,int age){
super(name,age);
C#版:class Base{
public Base(String name,int age)
this.name =
this.age =
}} class Child : Base{
public Child(string name,int age) :base (name,age)
}} 别忘了给java版添加get/set, 给C#版添加Property, 不然这样做基本没什么意义。
用this指针基类名称::基类的构造函数(,(派生类名称*)&派生类的对象) 这样就只调用了基类的构造函数了
其他类似问题
为您推荐:
构造函数的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁C++派生类的构造函数和析构函数执行顺序及其构造形式
在C++程序员的面试中,经常会出现派生类与基类的构造函数、析构函数的执行顺序。其实这是一个很基本的问题,没有什么难度,只需要记住就OK了。&
1.派生类的构造函数和析构函数的执行顺序
首先执行基类的构造函数,随后执行派生类的构造函数,当撤销派生类对象时,限执行派生类的析构函数,再执行基类的析构函数。
2.派生类构造函数和析构函数的构造原则
1)派生类不能继承基类中的构造函数和析构函数。
当基类含有带参数的构造函数时,派生类必须定义构造函数,以提供把参数传递给基类构造函数的途径。
派生类构造函数名(参数表):基类构造函数名(参数表)
&&&&&&&&&&
&&&&&&&&&&
&&&&&&&&&&
2)当派生类中还有对象成员时,其构造函数的一般形式为:
派生类构造函数名(参数表):基类构造函数名(参数表),对象成员名 1(参数表),……对象成
员名 n(参数表)
&&&&&&&&&&//……
&&&&执行顺序:
&&&&&&&&基类的构造函数
对象成员的构造函数
派生类的构造函数
&&&&1.当基类构造函数不带参数时,派生类不一定需要定义构造函数,然而当基
类的析构函数哪怕只有一个参数,也要为派生类定义构造函数,甚至所定义的派 生类析构函数的函数体可能为空,仅仅起到传递参数的作用
&2.当基类使用缺省构造函数时或不带参数的构造函数时,则在派生类中定义
构造函数时,可以省略:基类构造函数名(参数表),此时若派生类不需要构造 函数,则可以不定义构造函数。
3.如果派生类的基类也是一个派生类,则每个派生类只需负责其直接基类的 构造,依次上溯。
4.如果析构函数是不带参数的,在派生类中是否要定义析构函数与它所属的
基类无关,故基类的析构函数不会因为派生类没有析构函数而得不到执行,他们各自是独立的
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 派生类 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信