C++中继承中遇到的构造函数问题

今天在开发时遇到了一个之前一直以为理所当然的构造函数问题。

先给总结:

子类在构造时,如果没有显式调用父类的构造函数,会先调用父类的默认构造函数(无参数的)

下面给出不同情况的例子

例子一:父类有默认的构造函数,子类的构造函数随便

#include <iostream>
class Base{
public:
	Base(){

	}
};

class Derive:public Base{
public:
	Derive(int a,int b){

	}
};

int main(){

	Derive c(1,2);

	return 0;
}

结果:编译通过,暂时不能说明问题。

例子二:父类没有默认的构造函数,子类的构造函数随便

#include <iostream>
class Base{
public:
	Base(int a){

	}
};

class Derive:public Base{
public:
	Derive(int a,int b){

	}
};

int main(){

	Derive c(1,2);

	return 0;
}

结果:编译错误,错误信息:[Error] no matching function for call to ‘Base::Base()‘

说明,子类的构造需要先调用父类的默认构造函数

例子三:父类没有默认的构造函数,子类的构造函数随便,但是显式调用了父类的构造函数

#include <iostream>
class Base{
public:
	Base(int a){

	}
};

class Derive:public Base{
public:
	Derive(int a,int b):Base(a){

	}
};

int main(){

	Derive c(1,2);

	return 0;
}

结果:编译成功

说明,显式调用父类的构造函数之后,不再调用父类的默认构造函数

例子四:父类没有默认的构造函数,子类的构造函数与父类的参数列表相同,但是没有显式调用父类的构造函数

#include <iostream>
class Base{
public:
	Base(int a){

	}
};

class Derive:public Base{
public:
	Derive(int a){

	}
};

int main(){

	Derive c(1);

	return 0;
}

结果:编译错误

说明,其实这种情况跟例子二的情况是一样的,只不过父类跟子类的构造函数参数一样,所以会给人感觉子类会调用父类相同参数的构造函数,但其实子类还是先调用父类的默认构造函数的。由于父类没有默认的构造函数,所以编译错误,错误信息跟例子二一样。

例子五(陷阱):父类跟子类的构造函数有相同的参数,且父类有默认的构造函数。子类没有显式调用父类的构造函数。

#include <iostream>
class Base{
public:
	Base(int a){
		this->a = a;
	}
	Base(){

	}
public:
	int a;
};

class Derive:public Base{
public:
	Derive(int a){

	}
};

int main(){

	Derive c(1);
	std::cout << c.a << std::endl;
	return 0;
}

结果:编译成功,运行输出结果为:3674912

说明,这种情况跟例子四如出一辙,只不过由于父类有默认的构造函数,所以才会编译成功。子类的带一个int参数的构造函数并没有调用父类带一个int参数的构造函数。

最后,再来一次总结:上面五个例子说明了,如果子类的构造函数中没有显式调用父类的构造函数,则先默认调用父类的默认构造函数。

换句话说,在使用继承时,如果父类没有默认的构造函数,则子类的构造函数应当显式地调用父类的自定义构造函数。

时间: 2024-10-29 03:58:50

C++中继承中遇到的构造函数问题的相关文章

谈谈c++中继承中的虚函数

c++继 承中的虚函数 c++是一种面向对象的编程语言的一个很明显的体现就是对继承机制的支持,c++中继承分很多种,按不同的分类有不同分类方法,比如可以按照基类的个数分为多继承和单继承,可以按照访问权限分为public继承.protected继承和private继承,按照是否是虚拟继承可以分为virtual继承和non-virtual继承.当然这里的分类标准都是有重叠的部分,比如,non-virtual继承又可以分为单继承和多继承.这里要讨论的是虚函数,因此主要从virtual和non-virt

多重继承,虚继承,MI继承中虚继承中构造函数的调用情况

先来测试一些普通的多重继承.其实这个是显而易见的. 测试代码: [cpp] view plain copy print? //测试多重继承中派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include <iostream> using namespace std; class base { public: base() { cout<<"base created!"<<endl; } ~base()

派生类的构造函数和析构函数和多继承中的二义性与虚函数

析构函数主要作用是对数据成员初始化. 1派生类的构造函数 派生类的构造函数定义的一般形式为: 派生类名::派生类名(基类所需形参,本类成员所需形参):基类1(基类1 参数表),基类2(基类2 参数表),···,基类n(基类n 参数表),对象成员1(对象1 参数表),对象成员2(对象2 参数表),···,对象成员m(对象m 参数表){ //本类基本类型数据成员初始化 } 如果使用基类无参构造函数,派生类构造函数形参表中不包含供给基类构造函数的参数.此时,系统会调用基类的默认构造函数.如果使用对象数

C++继承中关于子类构造函数的写法

转载于:http://www.cnblogs.com/kaige/p/cplusplus_virtual_inheritance_derived_class_constructor.html 构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法).因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法. 如果没有显式的构造函数,编译器会给一个默认的构造函数,并且该默认的构造函数仅仅在没

(C++)C++类继承中的构造函数和析构函数

思想: 在C++的类继承中, 建立对象时,首先调用基类的构造函数,然后在调用下一个派生类的构造函数,依次类推: 析构对象时,其顺序正好与构造相反: 例子: #include <iostream> using namespace std; class Shape{ public: void Draw() {cout<<"Base::Draw()"<<endl;} void Erase() {cout<<"Base::Erase()

继承中的构造函数

构造函数的作用:初始化对象, 继承的两个特性:单根性,和传递性. 一:一个类中可以存在多个构造函数,他们实现一个重载关系.构造函数之间会造成冗余的情况. 列如: 解决办法就是用this来解决冗余问题. this 有两个作用:1.表示当前类的对象.2.解决本类中出现的冗余问题. 二:继承中构造函数. 继承:即子类(派生类)继承父类(基类)的属性和方法,在这个过程中发生的过程: 1.为子类实例化对象时,系统会默认为父类实例化对象,(默认调用的是空构造函数)调用父类的属性和方法,然后才实例化子类对象.

C++继承中析构函数 构造函数的调用顺序以及虚析构函数

首先说说构造函数.大家都知道构造函数里就能够调用成员变量,而继承中子类是把基类的成员变成自己的成员,那么也就是说子类在构造函数里就能够调用基类的成员了,这就说明创建子类的时候必须先调用基类的构造函数,仅仅有这样子类才干在构造函数里使用基类的成员,所以是创建子类时先调用基类的构造函数然后再调用自己的构造函数.通俗点说,你要用某些物品.但这些物品你没办法自己生产,自然就要等别人生产出来,你才干拿来用. 接着就是析构函数了,上面说到子类是将基类的成员变成自己的成员,那么基类就会仅仅存在子类中直到子类调

C++多重继承,菱形继承中构造函数的调用顺序

C++中多重继承不免会出现钻石继承,也就是继承类的两个基类同时又是同一个基类的继承类,当创建一个对象的时候,他们是按照什么样的顺序调用构造函数的呢. 如果不进行虚拟继承: class Base { public: Base() { cout<<"Base默认构造函数调用"<<endl; } Base(int i) { cout<<"Base参数构造函数调用"<<endl; cout<<i<<en

继承中的的构造函数问题

代码如下: 1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Teacher t1 = new Teacher("许大虾", 23, "[email protected]", 10000); 6 Student s1 = new Student("许大虾", 23, "[email protected]", "100001"); 7 }