C++中的三种继承方式
1,被忽略的细节:
1,冒号( :)表示继承关系,Parent 表示被继承的类,public 的意义是什么?
class Parent
{ }; class Child : public Parent
{ };
2,有趣的问题:
1,是否可以将继承语句中的 public 换成 protected 或者 private?如果可以,与 public 继承有什么区别?
3,有趣的尝试编程实验:
#include <iostream>
#include <string> using namespace std; class Parent
{
}; class Child_A : public Parent
{
}; class Child_B : protected Parent
{
}; class Child_C : private Parent
{
}; int main()
{
return ;
}
1,protected 和 private 地位对等,推理的角度可以过,实际的编译结果也是同样的结论;
2,本文主要分析这三种继承方式有何不同;
4,不同的继承方式(这是父类成员在子类中被外界访问的级别):
1,C++ 中支持三种不同的继承方式;
1,public 继承:
1,父类成员在子类中保持原有访问级别;
2,private 继承:
1,父类成员在子类中变为私有成员;
3,protected 继承:
1,父类中的公有成员变为保护成员,其它成员保持不变;
2,继承成员的属性:

1,Max{继承方式,父类成员访问属性};
2,C++ 中的默认继承方式为 private;
3,继承与访问级别深度实践编程实验:
#include <iostream>
#include <string> using namespace std; class Parent
{
protected:
int m_a;
protected:
int m_b;
public:
int m_c; void set(int a, int b, int c)
{
m_a = a;
m_b = b;
m_c = c;
}
}; class Child_A : public Parent
{
public:
void print()
{
cout << "m_a" << m_a << endl;
cout << "m_b" << m_b << endl;
cout << "m_c" << m_c << endl;
}
}; class Child_B : protected Parent
{
public:
void print()
{
cout << "m_a" << m_a << endl;
cout << "m_b" << m_b << endl;
cout << "m_c" << m_c << endl;
}
}; class Child_C : private Parent
{
public:
void print()
{
cout << "m_a" << m_a << endl;
cout << "m_b" << m_b << endl;
cout << "m_c" << m_c << endl;
}
}; int main()
{
Child_A a;
Child_B b;
Child_C c; a.m_c = ;
// b.m_c = 100; // Child_B 保护继承自 Parent, 所以所有 public 成员全部变成了 protected 成员, 因此外界无法访问;
// c.m_c = 100; // Child_C 私有继承自 Parent, 所以所有的成员全部变成了 private 成员, 因此外界无法访问; a.set(, , );
// b.set(2, 2, 2); // 保护继承;
// c.set(3, 3, 3); // 私有继承; a.print(); // 继承方式只影响继承自父类成员的访问方式,外界访问子类方式无影响;
b.print(); // 继承方式只影响继承自父类成员的访问方式,外界访问子类方式无影响;
c.print(); // 继承方式只影响继承自父类成员的访问方式,外界访问子类方式无影响; return ;
}
1,父类中的访问级别影响着子类的访问,但是继承级别不影响子类的访问、影响其它外部类访问父类中的成员;
5,遗憾的事实:
1,一般而言,大型的 C++ 工程项目中只使用 public 继承;
1,这已经足够了;
2,保护继承和私有继承根本就没什么用;
2,C++ 的派生语言只支持一种继承方式(public 继承);
1,Java、C# 等语言只有一种继承方式即 public 继承方式;
3,protected 和 private 继承带来的复杂性远大于实用性;
1,仅在学术研究领域研究;
6,C++ 派生语言初探编程实验:
1,D 语言(在 Linux 中用 gdc 编译,生成 *.out 文件):
module D_Demo; // 将下面的所有代码定义为模块,模块名字为
D_Demo; import std.stdio; // import 同 include
import std.string; // import 同 include class Obj // 这里定义了一个 Obj 类
{
protected:
string mName;
string mInfo; public:
this() // 这是 D 语言中的构造函数,D 语言中的构造函数统一的用 this 这个关键字表示,由 C++ 进化而来;
{
mName = "Object";
mInfo = "";
} string name() // 定义两个成员函数;
{
return mName;
} string info()
{
return mInfo;
}
} class Point : Obj // 定义了一个类 Point,其继承自 Obj,D 语言中的继承方式默认的是 public 继承;
{
private:
int mX;
int mY; public:
this(int x, int y)
{
mX = x;
mY = y;
mName = "Point";
mInfo = format("P(%d, %d)", mX, mY); // 和 C 语言中的语法规则一样;
} int x()
{
return mX;
} int y()
{
return mY;
}
} void main(string[] args) // 程序运行的入口;
{
writefln("D Demo"); // D Demo;打印语句之后空一行,同 printf; Point p = new Point(, ); // 动态生成 Point 对象; writefln(p.name()); // Point,公有继承;
writefln(p.info()); // P(1, 2),公有继承;
}
1,没学过 D 语言,但是要读懂 D 语言的代码是比较容易的;
2,如果因工作需要要学习 D 语言程序设计,将是轻而易举的事情;
2,C# 语言(Linux 中用 gmcs 编译,生成 *.exe 文件):
class Obj // 定义一个类 Obj;
{
protected string mName; // 访问属性 protected;
protected string mInfo; public Obj() // 无返回值,函数名同类名,即构造函数,访问属性为 public;
{
mName = "Object";
mInfo = "";
} public string name()
{
return mName;
} public string info()
{
return mInfo;
}
} class Point : Obj // 定义一个类 Point,继承自 Obj,只有一种 public 继承方式;
{ private int mX;
private int mY; public Point(int x, int y) // 构造函数;
{
mX = x;
mY = y;
mName = "Point";
mInfo = "P(" + mX + ", " + mY + ")"; // 通过 + 操作符来连接字符串和整型变量,最终得到一个字符串;C++ 中可以通过重载全局的 + 操作符就能够连接一个字符串和一个整型变量最终得到一个字符串,别的语言中的特性,不明白的话,考虑下在 C++ 中如何实现;
} public int x()
{
return mX;
} public int y()
{
return mY;
}
} class Program
{
public static void Main(string[] args) // 程序入口
{
System.Console.WriteLine("C# Demo"); // C# Demo Point p = new Point(, ); System.Console.WriteLine(p.name()); // Point
System.Console.WriteLine(p.info()); // P(1, 2) }
}
3,Java 程序:
class Obj
{
protected String mName;
protected String mInfo; public Obj()
{
mName = "Object";
mInfo = "";
} public String name()
{
return mName;
} public String info()
{
return mInfo;
}
} class Point extends Obj // extends 表示公有继承,更加直观;
{ private int mX;
private int mY; public Point(int x, int y)
{
mX = x;
mY = y;
mName = "Point";
mInfo = "P(" + mX + ", " + mY + ")";
} public int x()
{
return mX;
} public int y()
{
return mY;
}
} class Program {
public static void main(String[] args){ // 程序运行如口
System.out.println("Java Demo"); // Java Demo Point p = new Point(1, 2); System.out.println(p.name()); // Point
System.out.println(p.info()); // P(1, 2)
}
}
1,现在已经有能力读懂 D、C#、Java 语言程序了;
1,C#、Java 可以从事网络开发、游戏开发;
2,D 语言可以从事系统开发;
2,工程里面,仅仅使用 public 继承就够了;
7,小结:
1,C++ 中支持 3 种不同的继承方式;
2,继承方式直接影响父类成员在子类中的访问属性;
3,一般而言,工程中只使用 public 的继承方式;
4,C++ 的派生语言中只支持 public 继承方式;
C++中的三种继承方式的更多相关文章
- C++ 中三种继承方式的理解
		一.公有继承(public inheritance) 1.概念:当类的继承方式为公有继承时,基类的公有成员和保护成员的访问属性在派生类中不变,而基类的私有成员不可以直接访问. 实验一下: 我们用代 ... 
- js的三种继承方式及其优缺点
		[转] 第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = ' ... 
- C++的三种继承方式简述
		C++对父类(也称基类)的继承有三种方式,分别为:public继承.protected继承.private继承.三种继承方式的不同在于继承之后子类的成员函数的"可继承性质". 在说 ... 
- C++继承(一) 三种继承方式
		继承定义 继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一. 继承就是不修改原有的类,直接利用原来的类的属性和方法并进行扩展.原来的类称为基类,继承的类称为派生类,他们的关系就像父子 ... 
- c++三种继承方式public,protect,private
		C++中的三种继承public,protected,private 三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员 ... 
- C++中的三种继承关系
		C++中的三种继承关系 先看类中声明成员时的三种访问权限 public : 可以被任意实体访问 protected : 只允许子类及本类的成员函数访问 private : 只允许本类的成员函数访问 在 ... 
- js oop中的三种继承方法
		JS OOP 中的三种继承方法: 很多读者关于js opp的继承比较模糊,本文总结了oop中的三种继承方法,以助于读者进行区分. <继承使用一个子类继承另一个父类,子类可以自动拥有父类的属性和方 ... 
- C++中的三种继承public,protected,private
		( c++默认class是private继承且class内的成员默认都是private struct 默认位public 继承,struct内成员默认是public ) 三种访问权限 public: ... 
- C++三种继承方式
		一.三种继承方式 继承方式不同,第一个不同是的是派生类继承基类后,各成员属性发生变化.第二个不同是派生类的对象能访问基类中哪些成员发生变化.表格中红色标注. 
随机推荐
- 【GDSOI2019】滑稽二乘法【数据结构】【LCT】
			Description 点数<=100000,操作数<=200000 Solution 经典的LCT维护子树路径信息的问题. 具体来说,我们对于每一个节点,它在splay上的子树对应了原树 ... 
- (Java多线程系列一)快速入门
			Java多线程快速入门 1.线程和进程的区别 进程是所有线程的集合,每一个线程是进程的一条执行路径. 2.多线程的应用场景 多线程主要体现在提高程序的效率,比如迅雷多线程下载,多线程分批发送短信等. ... 
- confluence -- 命令行备份还原
			备份:confluence每日凌晨2:00都在 /data/atlassian/application-data/confluence/backups/ 下生成备份包,其中包括文档,附件,用户 还原: ... 
- Springboot集成Swagger操作步骤
			特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ... 
- mybatis plus table doesn't exists
			使用@TableName 注解即可 实际上就是建立bean与表名的连接 
- TCP定时器 之 坚持定时器
			坚持定时器在接收方通告接收窗口为0,阻止发送端继续发送数据时设定. 由于连接接收端的发送窗口通告不可靠(只有数据才会确认,ACK不会确认),如果一个确认丢失了,双方就有可能因为等待对方而使连接终止:接 ... 
- python安装的各种问题
			在windows上安装python下载mis安装即可. 环境用elipse即可,需要下载pydev插件,配置解释器. 如需用到matplotlib,安装顺序为matplot,numpy,dateuti ... 
- Kotlin之定义变量
			java : int n = 30 ; final int m = 30 ; float k = 2.5f; string s = "sss"; short i = 5; bool ... 
- centos7.7下docker与k8s安装(DevOps三)
			1.系统配置 centos7.7 docker 1.13.1 centos7下安装docker:https://www.cnblogs.com/pu20065226/p/10536744.html 2 ... 
- git clone的代码没有前端代码
			需要切换到文件夹目录下,然后 git checkout dev 切换到开发环境(其实是切换到了dev分支) 后来查看分支,发现有两个分支:master 和 dev . ================ ... 
