C++基类和派生类的构造函数
派生类不能继承基类的构造函数,若想通过派生类来对基类的private的变量成员进行初始化则需要:
通过派生类的构造函数来调用基类的构造函数完成基类成员变量的初始化.
看下面的例子:
#include <iostream>
#include<string> using namespace std; class People {
private:
char *m_name;
int m_age; public:
People(char*, int);
}; People::People(char* name,int age):m_name(name),m_age(age){} class Student : public People {
//此处的public是将其基类:People 的成员以其在People内的级别于Student中继承,
//即成员在基类中是什么级别就以什么级别被派生类继承.protected则是将public级别的成员改为protected被派生类继承,private则是
//全变成private被派生类继承
private:
float m_score; public:
Student(char* name, int age, float score);
//void display();
}; Student::Student(char*name,int age,float score):People(name,age),m_score(score){
cout << " 姓名: " << name << " 年龄: " << age << " 成绩: " << score << endl;
} //在此处调用基类的构造函数,可调换基类构造函数的顺序,当然相应的形参位置也要变. /*void Student::display() {
cout <<" 姓名: "<< m_name << " 年龄: " << m_age << " 成绩: " << m_score << endl;
}*/ int main()
{
Student *pstu = new Student("Chan",21,99);
//pstu->display();
return 0;
}
错误用法:
Student::Student(char *name, int age, float score){
People(name, age);
m_score = score;
} //error
因为派生类没有继承基类的构造函数,所以不能调用基类的构造函数.
构造函数调用顺序:
先是调用基类的构造函数,然后再调用派生类的构造函数,多继承亦然.
注意事项:多继承如 A -- B -- C 只能直接调用基类构造函数,不能间接调用基类构造函数,即B可调用A,但C不可调用A.
/*C++ 这样规定是有道理的,因为我们在 C 中调用了 B 的构造函数,B 又调用了 A 的构造函数,相当于 C 间接地(或者说隐式地)调用了 A 的构造函数,如果再在 C 中显式地调用 A 的构造函数,那么 A 的构造函数就被调用了两次,相应地,初始化工作也做了两次,这不仅是多余的,还会浪费CPU时间以及内存,毫无益处,所以 C++ 禁止在 C 中显式地调用 A 的构造函数。 */
通过派生类创建对象时必须要调用基类的构造函数,这是语法规定。换句话说,定义派生类构造函数时最好指明基类构造函数;如果不指明,就调用基类的默认构造函数(不带参数的构造函数);如果没有默认构造函数,那么编译失败。
请看下面的例子:
#include<iostream>
#include<string> using namespace std; class People {
private:
char* m_name;
int m_age; public:
People();
People(char*, int);
}; People::People(char* name, int age) :m_name(name), m_age(age) {};
People::People() :m_name("xxxx"), m_age() {}; class Student : public People {
private:
float m_score; public:
Student();
Student(char *name, int age, float score);
}; Student::Student() :People(), m_score() {
cout << "姓名:xxxx" << " 年龄:00" << " 成绩:0" << endl;
}; Student::Student(char* name, int age, float score) :People(name, age), m_score(score) {
cout << "姓名:" <<name<< " 年龄:" <<age<< " 成绩:" <<score<< endl;
}; int main() {
Student *pstu = new Student;
Student *pstu1 = new Student("陈东",,88.5);
return ;
}
如果将People(name, age)去掉,也会调用默认构造函数.(上面代码执行后看不出来,需修改People类的private为protected,再在student类中写void display())
void Student::display(){
cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<"。"<<endl;
}
附:https://blog.csdn.net/qq_23996069/article/details/89344816
转载来源:http://c.biancheng.net/view/2276.html
C++基类和派生类的构造函数的更多相关文章
- 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
[源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...
- C++学习笔记(6)----基类和派生类的构造函数和析构函数的执行顺序
基类和派生类:构造函数和析构函数的执行顺序 在Visual Studio中,新建控制台工程,构造类如下: #include<iostream> using namespace std; c ...
- c++中基类与派生类中隐含的this指针的分析
先不要看结果,看一下你是否真正了解了this指针? #include<iostream> using namespace std; class Parent{ public: int x; ...
- 基类和派生类--this
基类指针在程序运行的时候的确指向的是一个派生类的对象,但指针的类型仍然是基类指针.C++是一种强类型语言,因此不能用基类指针类型的指针直接调用派生类:而且,同一个类可能有多种不同的派生类,因此不知道实 ...
- C++:基类与派生类对象之间的赋值兼容关系
4.5 基类与派生类对象之间的赋值兼容关系 在一定条件下,不同类型的数据之间可以进行类型转换,例如可以将整型数据赋给双精度型变量. 在赋值之前,先把整型数据转换为双精度型数据,然后再把它双精度型变量. ...
- C++:基类和派生类
4.1 派生类的声明 继承实例如下: class Person{ //声明基类Person public: void print() { cout<<"name:"&l ...
- C++基类和派生类之间的转换
本文讲解内容的前提是派生类继承基类的方式是公有继承,关键字public 以下程序为讲解用例. #include<iostream> using namespace std; class A ...
- Java基类和派生类
背景:对基类和派生类有更清晰的认识. 从外部看来,派生类是一个与基类具有相同接口的新类,或许还会有一些额外的的方法和域 .但继承并不仅仅是类的复用.当创建了一个派生类的对象时,该类包含了一个基类的子对 ...
- c++ 的类 和 类继承, 什么是c++中的基类和派生类?
闲云潭影日悠悠,物换星移几度秋 你既然已经做出了选择, 又何必去问为什么选择.鬼谷绝学的要义, 从来都不是回答, 而是抉与择 普通类 #ifndef TABTENN0_H_ #define TABTE ...
- DI容器Ninject在管理接口和实现、基类和派生类并实现依赖注入方面的实例
当一个类依赖于另一个具体类的时候,这样很容易形成两者间的"强耦合"关系.我们通常根据具体类抽象出一个接口,然后让类来依赖这个接口,这样就形成了"松耦合"关系,有 ...
随机推荐
- context:component-scan 和 mvc:annotation-driven
前言 Spring MVC 框架提供了几种不同的配置元素来帮助和指示 Spring 容器管理以及注入 bean . 常用的几个 XML 配置是 context:component-scan mvc:a ...
- 快速傅里叶变换与快速数论变换瞎学笔记$QwQ$
$umm$先预警下想入门$FFT$就不要康我滴学习笔记了,,, 就,我学习笔记基本上是我大概$get$之后通过写$blog$加强理解加深记忆这样儿的,有些姿势点我可能会直接$skip$什么的,所以对除 ...
- js的class基础
title: js的class基础 date: 2020-01-04 13:34:44 tags: --- 基本写法 let log = console.log; class people { con ...
- 1068 万绿丛中一点红 (20分)C语言
对于计算机而言,颜色不过是像素点对应的一个 24 位的数值.现给定一幅分辨率为 M×N 的画,要求你找出万绿丛中的一点红,即有独一无二颜色的那个像素点,并且该点的颜色与其周围 8 个相邻像素的颜色差充 ...
- 1089 狼人杀-简单版 (20 分)C语言
以下文字摘自<灵机一动·好玩的数学>:"狼人杀"游戏分为狼人.好人两大阵营.在一局"狼人杀"游戏中,1 号玩家说:"2 号是狼人" ...
- React框架随笔
React框架随笔 现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了 ...
- ENS 域名注册表智能合约(ENSRegistry.sol)解析
ENS 注册表合约是 ENS 系统中的核心合约,了解这个合约可以敲开我们理解 ENS 域名系统的大门. 打开下面的折叠区域可以查看用 Solidity 语言编写的详细代码.当前部署在以太坊中的 ENS ...
- JavaScript系列之回调函数callback
JavaScript系列之回调函数callback JavaScript回调函数的使用是很常见的,引用官方回调函数的定义: A callback is a function that is passe ...
- # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)
目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...
- django.db.migrations.exceptions.MigrationSchemaMissing和raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)
1.使用Python3.7 + Django2.2 + MySQL 5.5 在执行(python manage.py migrate)命令时出现错误django.db.migrations.excep ...