继承中参数传递及调用顺序

一、简单派生类的构造函数传参

C++语言的继承特性,指子类可以继承父类的属性和行为,并可以重新定义或添加新的属性和行为。父类中为private型的属性和行为虽然被继承,但是子类中仍不能访问。在继承机制下,构造函数是不能被继承的,所以基类构造函数的参数要由子类构造函数传!

单一继承的子类构造函数的声明(.h中)形式为:

派生类构造函数名(参数总表) ();

单一继承的子类构造函数的定义(.cpp中)形式为:

派生类名::派生类构造函数名(参数总表) : 基类构造函数名 (参数名表)

{

派生类新增成员的初始化语句;

};

定义派生类的构造函数时,在构造函数的参数总表中包括基类构造函数所需的参数和派生类新增的数据成员初始化所需的参数。冒号后面基类构造函数名 (参数名表),表示要调用基类的构造函数。

#include "stdafx.h"

#include <iostream>
#include <string>
using namespace std;    

class parent
{
public:
	parent(int a,int b)  //基类构造函数,需要传入两个参数
	{
		//基类的初始化
		this->a = a;
		this->b = b;
	}
public:
	int a,b;
};

class child:public parent
{
public:
	child(int a,int b,int c); //子类构造函数含参数总表(所有参数)
	void ShowTest()
	{
		cout<<"a = "<<a<<endl;
		cout<<"b = "<<b<<endl;
		cout<<"c = "<<c<<endl;
	}

public:
	int c;
};

//子类构造函数的定义,利用初始化表括进行参数初始化
child::child(int a,int b,int c):parent(a,b)
{
	//子类参数的初始化
	this->c = c;
}

void test()
{
	child t1(1,2,3);
	t1.ShowTest();
}

int _tmain(int argc, _TCHAR* argv[])
{
	test();
	system("pause");
	return 0;
}

测试结果:

二、复杂派生类的构造函数和析构函数

一个派生类中新增加的成员可以是简单的数据成员,也可以是类对象。派生类需要初始化的数据有三部分:继承的成员、新增类对象的成员和新增普通成员。

这种复杂派生类的构造函数定义如下:

派生类名::派生类构造函数名(总参数表)

:基类构造函数名1 (参数表1),

基类构造函数名2 (参数表2),    ……

子对象名1(参数表n),

子对象名2(数表n+1)    ……

{

派生类新增普通数据成员的初始化;

}

// test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <iostream>
#include <string>
using namespace std;    

class A
{
public:
	A(){}
	A(int i){a = i;}
	~A(){}
	void Print(){
		cout<<"a = "<<a<<endl;
	}
	int Geta(){ return a;}
private:
	int a;
};

class B
{
public:
	B(){}
	B(int i){b = i;}
	~B(){}
	void Print(){
		cout<<"b = "<<b<<endl;
	}
	int Getb(){ return b;}
private:
	int b;
};

class C:public A
{
public:
	C(void){}
	C(int i,int j,int k):A(i),b1(j)
	{
		c = k;

	}

	~C(void){}
	void Print(){
		cout<<"a = "<<Geta()<<endl;
		cout<<"b = "<<b1.Getb()<<endl;
		cout<<"c = "<<c<<endl;
	}
private:
	int c;
	B b1;
};

void test()
{
	C c1(1,2,3);
	c1.Print();
}

int _tmain(int argc, _TCHAR* argv[])
{
	test();
	system("pause");
	return 0;
}

测试结果:

注:在vs2010编译环境下,若将声明处C(void){}改为C(void);则会出现编译错误:

1).obj : error LNK2019: 无法解析的外部符号 "public: __thiscall C::C(void)" ([email protected]@[email protected]),该符号在函数 "void __cdecl test(void)" ([email protected]@YAXXZ) 中被引用

2)fatal error LNK1120: 1 个无法解析的外部命令

原因是第二种方法默认只声明了构造函数,并没有实现。第一种则为函数定义实现方式,虽然“;”与{}作用相似,但此处不一样!!!

知识点总结:

派生类构造函数的调用顺序如下:

Step1:基类构造函数。按它们在派生类定义中的先后顺序,依次调用。

Step2:内嵌对象的构造函数。按它们在派生类定义中的先后顺序,依次调用。

Step3:派生类的构造函数。

复杂派生类的析构函数,只需要编写对新增普通成员的善后处理,而对类对象和基类的善后工作是由类对象和基类的析构函数完成的。析构函数的调用顺序与构造函数相反。

时间: 2024-10-20 15:20:57

继承中参数传递及调用顺序的相关文章

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

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

继承中代码的执行顺序

在继承中代码的执行顺序为:1.父类静态对象和静态代码块   2.子类静态对象和静态代码块 3.父类非静态对象和非静态代码块  4.父类构造函数 5.子类非静态对象和非静态代码块  6.子类构造函数 1.对于本题来说:在只想new Sub(5)的时候,父类先初始化了 int flag = 1,然后执行父类的构造函数Super(),父类构造函数中执行的test()方法,因子类是重写了test()方法的,因此父类构造函数中的test()方法实际执行的是子类的test()方法,所以输出为Sub.test

JAVA继承中的构造器调用

关于继承中的构造器调用和调用顺序,做了个小测试,如下: class People {  String name;    //2,第二步,调用此无参构造器  public People() {   System.out.println(".父类的无参构造器");  }    //5,调用此有参构造器  public People(String name) {   System.out.println(".父类的有参构造器");   this.name = name;

多重继承,虚继承,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()

java中构造器的调用顺序

在编程的过程中,我们经常会遇到多个类的继承问题,那么多个类的构造器是按照什么顺序调用的呢? 先看一段代码: 1 public class Meal { 2 public Meal() { 3 System.out.println("meal constructor() "); 4 } 5 } 6 7 public class Bread { 8 public Bread() { 9 System.out.println("bread constructor() ")

转:UIViewController中各方法调用顺序及功能详解

UIViewController中loadView, viewDidLoad, viewWillUnload, viewDidUnload, viewWillAppear, viewDidAppear, viewWillLayoutSubviews,viewDidLayoutSubviews,viewWillDisappear, viewDidDisappear方法,按照调用顺序说明如下: 调试日志: 1 2 3 4 5 6 7 8 9 2013-07-14 12:15:49.048 VCTes

UIViewController中各方法调用顺序及功能详解

UIViewController中loadView, viewDidLoad, viewWillUnload, viewDidUnload, viewWillAppear, viewDidAppear, viewWillLayoutSubviews,viewDidLayoutSubviews,viewWillDisappear, viewDidDisappear方法,按照调用顺序说明如下: 调试日志: 1 2 3 4 5 6 7 8 9 2013-07-14 12:15:49.048 VCTes

Java 继承中构造方法的执行顺序问题

在Java中,如果一个类没有任何显式创建的构造器则该类默认会有一个无参构造器:如果显式创建了有参构造器则该类就不再有默认无参构造器. 在Java继承中,构造器并不能被继承,而是被显示或隐式调用. 1.子类的构造方法中必须调用其基类的构造方法(显示或隐式) 1.1.若是显示调用,则可以通过 super(argument_list) 来调用,且super调用必须在首行以保证子类对象从所有直接或间接父类中继承的实例变量都被正确地初始化(this关键字可以调用本类中的其他构造器,也必须在首句,因此thi

(转)UIViewController中各方法调用顺序及功能详解

目录(?)[-] 1 initWithNibNamebundle 2 loadView 3 viewDidLoad 4 viewWillAppear 5 viewDidAppear 6 viewWillLayoutSubviews 7 viewDidLayoutSubviews 8 viewWillDisappear 9 viewDidDisappear 10 viewWillUnload 11 viewDidUnload UIViewController中loadView, viewDidLo