之前只注意过访问控制与继承的关系,这边不多说,今天看到代码看到virtual放在private里,并且还有派生类没有override public里的virtual,此时调用时啥情况了,这边有点晕,看下面代码

首先最基本的多态代码

#include <iostream>
#include <string> using namespace std; class animal
{
public:
//animal();
//~animal();
virtual void speakout()
{
cout << "animal voice voice voice" << endl;
}
};
class cat :public animal
{
public:
//cat();
//~cat();
virtual void speakout()
{
cout << "cat miao miao miao" << endl;
}
}; int main()
{
cat ocat;
animal *panimal = &ocat;
panimal->speakout();
getchar(); }

运行结果没有任何问题,结果如下:

如果virtual是私有的,代码如下:

#include <iostream>
#include <string> using namespace std; class animal
{
private:
//animal();
//~animal();
virtual void speakout()
{
cout << "animal voice voice voice" << endl;
}
};
class cat :public animal
{
private:
//cat();
//~cat();
virtual void speakout()
{
cout << "cat miao miao miao" << endl;
}
}; int main()
{
cat ocat;
animal *panimal = &ocat;
panimal->speakout();
getchar(); }

编译就会报错,报错如下,实际上此时放在private里的时候,virtual有和没有一样,都是类的私有成员,只有类内部成员以及友元能够访问

主要是考虑下面一种特殊情况,基类里有virtual A(),派生类继承的时候没有override A(),切A()会调用私有的private virtual,代码如下:

#include <iostream>
#include <string> using namespace std; class animal
{
public:
virtual void speak()
{
speakout();
}
private:
//animal();
//~animal();
virtual void speakout()
{
cout << "animal voice voice voice" << endl;
}
};
class cat :public animal
{
private:
//cat();
//~cat();
virtual void speakout()
{
cout << "cat miao miao miao" << endl;
}
}; int main()
{
cat ocat;
animal *panimal = &ocat;
panimal->speak();
getchar(); }

其运行结果如下:

再对比如下代码:

#include <iostream>
#include <string> using namespace std; class animal
{
public:
virtual void speak()
{
speakout();
}
private:
//animal();
//~animal();
void speakout()
{
cout << "animal voice voice voice" << endl;
}
};
class cat :public animal
{
private:
//cat();
//~cat();
void speakout()
{
cout << "cat miao miao miao" << endl;
}
}; int main()
{
cat ocat;
animal *panimal = &ocat;
panimal->speak();
getchar(); }

其运行结果如下:

说明此时的private里的virtual是不能去掉的,如果去掉的话,speak()调用的是类本身的私有函数speakout(),否则调用的是派生类cat里的speakout()函数

当派生类继承了基类里的public speak(),哪怕没做任何修改,去掉private里的virtual,结果调用也是派生类里的speakout(),代码如下:

#include <iostream>
#include <string> using namespace std; class animal
{
public:
virtual void speak()
{
speakout();
}
private:
//animal();
//~animal();
void speakout()
{
cout << "animal voice voice voice" << endl;
}
};
class cat :public animal
{
public:
virtual void speak()
{
speakout();
}
private:
//cat();
//~cat();
void speakout()
{
cout << "cat miao miao miao" << endl;
}
}; int main()
{
cat ocat;
animal *panimal = &ocat;
panimal->speak();
getchar(); }

  

运行结果如下:

只能猜测派生类没有继承基类里的public speak(),panimal->speak()调用的是基类里的speak()函数,这时候间接调用的speakout()如果是虚函数则调用派生类的(哪怕是private),否则调用基类的

当继承了基类里的public speak(),panimal->speak()直接就调用了派生类里的speakout(),这时候speakout()是不是虚函数已没有关系

这边的原理我也没搞懂,只知道现在用起来是这样,如果哪位大神知道原理的能和我讲下,不甚感激!!!!!!!!!!!

  

(继承)virtual与访问控制的更多相关文章

  1. C++(三十八) — 继承方式、访问控制、构造和析构、虚继承

    派生类继承了基类的所有成员,但不包含 构造函数.析构函数.默认赋值运算符.  1.继承方式.访问控制 (1)protected属性:类的对象不能访问该属性成员,但派生类的成员函数可以访问基类的prot ...

  2. C++对象内存分布(3) - 菱形继承(virtual)

    1.前言 本篇文章的全部代码样例.假设是windows上编译执行.则使用的是visual studio 2013.假设是RHEL6.5平台(linux kernal: 2.6.32-431.el6.i ...

  3. inheritance,菱形继承, 虚继承,virtual

    //菱形继承   |||||||   虚继承 #include <iostream> using namespace std; class R {     int r; public:   ...

  4. C++学习之继承中的访问控制

    我们通常认为一个类有两种不同的用户:普通用户 和 类的实现者.其中,普通用户编写的代码使用类的对象,这部分代码只能访问类的公有(接口)成员:实现者则负责编写类的成员和友元的代码,成员和友元既能访问类的 ...

  5. C++ 类的继承一(访问控制)

    //类的继承 #include<iostream> using namespace std; /* 面向对象中的继承类之间的父子关系 1.子类拥有父类所有的成员属性和成员函数(包括私有成员 ...

  6. C++复习:继承与派生

    1继承概念 面向对象程序设计有4个主要特点:抽象.封装.继承和多态性.说了类和对象,了解了面向对象程序设计的两个重要特征一数据抽象与封装,已经能够设计出基于对象的程序,这是面向对象程序设计的基础. 要 ...

  7. C++基础 (6) 第六天 继承 虚函数 虚继承 多态 虚函数

    继承是一种耦合度很强的关系 和父类代码很多都重复的 2 继承的概念 3 继承的概念和推演 语法: class 派生类:访问修饰符 基类 代码: … … 4 继承方式与访问控制权限 相对的说法: 爹派生 ...

  8. C++ 的多继承与虚继承

    C++之多继承与虚继承   1. 多继承 1.1 多继承概念 一个类有多个直接基类的继承关系称为多继承 多继承声明语法 class 派生类名 : 访问控制 基类名1, 访问控制 基类名2, ... { ...

  9. Effective C++ -- 继承和面向对象设计

    32.确保你的public继承了模is-a关系 public继承意味着is-a关系(里氏替换原则),一切适用于基类也适用于派生类. 矩形继承正方形问题: 可实施与矩形的操作无法实施与正方形 在编程领域 ...

随机推荐

  1. js实现多行图片点击(自动)左右无缝轮播特效

    /*效果图*/ HTML:    <div class="scroll">       <div class="picbox">     ...

  2. SpringMVC 自定义全局日期转换器

    第一步: 编写自定义转换器的类 /* * 自定义日期转换器 */ public class CustomDateConverter implements Converter<String, Da ...

  3. QQ_MultiTalkServer

    package test_teacher;import java.net.*;import java.io.*;public class MultiTalkServer{    public stat ...

  4. 测试页面,页面里边一次加载50张不同的图片,每张5M以上,查看浏览器的内存使用情况

    测试页面 1.需要你写个测试页面,页面里边一次加载50张不同的图片,每张5M,查看浏览器的内存使用情况 2.可以10张 递增的方式测试 3.图片需要缩放,比如所有图片缩放成600*800的比例 目的 ...

  5. canvas与svg区别

    canvas与svg区别 和SVG比起来有两个弱点,一个是画布里的内容是独立的,不能当成html元素:二是CANVAS是属于位图格式,而SVG是矢量图,可以平滑放大. HTML5的canvas画出来的 ...

  6. 基于jquery 的分页插件,前端实现假分页效果

    上次分享了一款jquery插件,现在依旧分享这个插件,不过上一次分享主要是用于regular框件,且每一页数据都是从后端获取过来的,这一次的分享主要是讲一次性获取完数据 然后手动进行分页.此需求基本上 ...

  7. 【Spark2.0源码学习】-1.概述

          Spark作为当前主流的分布式计算框架,其高效性.通用性.易用性使其得到广泛的关注,本系列博客不会介绍其原理.安装与使用相关知识,将会从源码角度进行深度分析,理解其背后的设计精髓,以便后续 ...

  8. JsonResult,Controller.Json

    表示一个类,该类用于将 JSON 格式的内容发送到响应. ContentEncoding:编码格式(最好按标准utf-8) ContentType: mime类型 Data:数据设置 JsonRequ ...

  9. Cf #353 D. Tree Construction

    题目链接:http://codeforces.com/problemset/problem/675/D 题目大意是将一个没有相同数字的数列中的数字依次插入到二叉搜索树中,问除了第一个数字以外,其他数字 ...

  10. javascript中类式继承和原型式继承的实现方法和区别

    在所有面向对象的编程中,继承是一个重要的话题.一般说来,在设计类的时候,我们希望能减少重复性的代码,并且尽量弱化对象间的耦合(让一个类继承另一个类可能会导致二者产生强耦合).关于“解耦”是程序设计中另 ...