#include<iostream>

//实现vptr指针初始化问题
using namespace std;
class Father
{
public:
Father (int f)
{
this->f=f;
//print();
}
virtual void print()
{
cout<<" 我是父类函数 \n";
}
private:
int f;
protected:
}; class Child:public Father
{
public:
Child(int c=0):Father(5)
{
//this->c=c;
//print();
}
virtual void print()
{
cout<<" 我是子类函数 \n";
}
private:
// int c;
protected:
}; void objplay(Father *base)
{
base->print();
} int main()
{
//Child c1(3);
//objplay(&c1); Father *pP = NULL;
Child *pC = NULL; Child array[] = {Child(1), Child(2), Child(3)};//这里还必须三个了。
pP = array;
pC = array; pP->print();//这里发生多态
pC->print(); //多态发生吗,不不不,不发生,这里只是调用子类的函数 pP++;
pC++;
pP->print();
pC->print(); //多态发生 pP++;
pC++;
pP->print();
pC->print(); //多态发生
system("pause");
return 0;
}

  

子类对象可以当作父类对象使用

子类对象可以直接赋值给父类对象

子类对象可以直接初始化父类对象

父类指针可以直接指向子类对象(这里仅仅指的是子类继承的父类的对象)

父类引用可以直接引用子类对象(这里仅仅指的是子类继承的父类的对象)

而子类的指针和应用就不可以指向父类对象

子类可以用父类的所有东西,只是对错而已,而父类不能用子类的任何东西。

所以上面两句和线面这一句并不矛盾。

曾经写的这句,现在不理解这句了?

多态的必备条件之一是必须是父类的指针或者引用,

而子类的指针和引用只会调用子类的函数,不会调用父类的,子类的指针和应用就不可以指向父类对象,

而其他的形式,比如:子类对象. XXX  这里就可以用父类的所有东西,而父类对象.XXX 就只能用自己的父类的成员。

所以综上所述,指针、引用和那个.是不一样的情况呢

是的,指针引用和直接对象.是不同的

调用函数的形参是父类的指针和引用可以指向子类的任何成员,但是调用函数的形参子类的指针和引用就只能指向自己的成员,不可以指向父类的。

子类对象成员调用 这里就可以用父类的所有东西,而父类对象的成员调用 就只能用自己的父类的成员

注意!!类定义的指针使用的时候,必须分配内存!!!

#include<iostream>
using namespace std;
class Father
{
public:
Father()
{
cout << "i am father \n";
}
virtual void print()
{
cout << " 我是父类的:";
cout << this->f << endl;
}
public:
int f;
}; class Child :public Father
{
public:
Child()
{
cout << "i am child \n";
}
virtual void print()
{
cout << " 我是子类的: ";
cout << this->f << endl;
cout << this->c << endl;
}
public:
int c;
};
void objplay(Father *tem1)
{
cout << "形参为 Father *tem1 的 tem1->f==========>";
cout << tem1->f << endl;
} void objplay2(Child *tem2)
{
cout << "形参为 Child *tem2 的 tem2->c==========>";
cout << tem2->c << endl;
cout << "形参为 Child *tem2 的 tem2->f==========>";
cout << tem2->f << endl;
}
int main()
{
Child c1;
Father f1;
c1.c = 5;
c1.f = 6;
cout << "c1.print()=====> ";
c1.print();//调用子类的 输出为6
f1.f = 7;
cout << "f1.print()=====> ";
f1.print();//调用父类的 输出为7
//Child *c2; 这样子写就会出错,因为指针使用的时候必须必须分配内存空间
Child *c2 = new Child;//一旦用类名字定义函数就会调用析构函数。
//Father *f2;
Father *f2 = new Father;
c2->c = 8;
c2->f = 9;
cout << "c2.print()=====> ";
c2->print();//调用子类的
f2->f = 10;
cout << "f2.print()=====> ";
f2->print();//调用父类的
objplay(&c1);// 这里虽然是父类的指针,但是指向的是子类的对象地址。所以调用显示的是子类的
objplay(&f1);//父类
objplay(c2);//这里居然也是调用的子类的值
objplay(f2);//父类
objplay2(&c1);
//objplay2(&f1); 出错
objplay2(c2);
//objplay2(f2); 出错
system("pause");
}

  

  

这个的例子就表明的很明显了。

这里面盲点很多,构造函数的调用问题,还有vptr指针的++问题(已解决)的更多相关文章

  1. [C++基础]在构造函数内部调用构造函数

    看下面的面试题: #include <iostream> using namespace std; struct CLS { int m_i; CLS( int i ) : m_i(i){ ...

  2. [C#解惑] #1 在构造函数内调用虚方法

    谜题 在C#中,用virtual关键字修饰的方法(属性.事件)称为虚方法(属性.事件),表示该方法可以由派生类重写(override).虚方法是.NET中的重要概念,可以说在某种程度上,虚方法使得多态 ...

  3. 关于在C#中构造函数中调用虚函数的问题

    在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...

  4. C++ 构造函数中调用虚函数

    我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数.这种调用都是对象已经构建完成的情况.那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: class A { p ...

  5. [Effective JavaScript 笔记]第38条:在子类的构造函数中调用父类的构造函数

    示例 场景类 场景图(scene)是在可视化的过程中(如游戏或图形仿真场景)描述一个场景的对象集合.一个简单的场景包含了在该场景中的所有对象(称角色),以及所有角色的预加载图像数据集,还包含一个底层图 ...

  6. C# 构造函数中调用虚方法的问题

    请看下面代码: using System; public class A{ public A(){ M1(); } public virtual void M1(){} } public class ...

  7. 避免在构造函数中调用虚方法(Do not call overridable methods in constructors)

    CLR中说道,不要在构造函数中调用虚方法,原因是假如被实例化的类型重写了虚方法,就会执行派生类型对虚方法的实现.但在这个时候,尚未完成对继承层次结构中所有字段的初始化.所以,调用虚方法会导致不可预测的 ...

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

    先来测试一些普通的多重继承.其实这个是显而易见的. 测试代码: //测试多重继承中派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include < ...

  9. 【校招面试 之 C/C++】第4题 拷贝构造函数被调用的3个时机

    1.被调用的3个时机: (1)直接初始化或拷贝初始化: (2)将一个对象作为一个实参传递,形参采用非指针或非引用的对象进行接收时(指针即指向了同一块空间,并未实现拷贝:而引用就是实参本身): (3)函 ...

随机推荐

  1. 程序猿职场心理学,教你三进三出“斩”HR拿offer(跳槽必看)

    摘要: 今天主要涉及到的是 HR 在面试时有哪些套路,这样可以见招拆招,斩获 offer! 今天主要涉及到的是 HR 在面试时有哪些套路,这样可以见招拆招,斩获 offer! 主要包括以下内容: 一. ...

  2. Finalize和Dispose的区别

    https://www.cnblogs.com/Jessy/articles/2552839.html

  3. Python入门之python可变对象与不可变对象

    本文分为如下几个部分 概念 地址问题 作为函数参数 可变参数在类中使用 函数默认参数 类的实现上的差异 概念 可变对象与不可变对象的区别在于对象本身是否可变. python内置的一些类型中 可变对象: ...

  4. 01: 安装zabbix server

    目录:Django其他篇 01: 安装zabbix server 02:zabbix-agent安装配置 及 web界面管理 03: zabbix API接口 对 主机.主机组.模板.应用集.监控项. ...

  5. 20145208 蔡野 《网络对抗》Exp4 恶意代码分析

    20145208 蔡野 <网络对抗>Exp4 恶意代码分析 问题回答 总结一下监控一个系统通常需要监控什么.用什么来监控. 监控一个系统通常需要监控这个系统的注册表,进程,端口,服务还有文 ...

  6. 什么是BFC?

    转载自知乎:https://zhuanlan.zhihu.com/p/25321647 一.常见定位方案 在讲 BFC 之前,我们先来了解一下常见的定位方案,定位方案是控制元素的布局,有三种常见方案: ...

  7. Hadoop新增和删除节点

    #新增节点 1.安装lunix,和以前一样的版本 2.初始化系统环境 2.1.设置静态ip vi /etc/sysconfig/network-scripts/ifcfg-eth0 //增加 #Adv ...

  8. Ubuntu上 配置Eclipse:安装CDT

    在最新的 Ubuntu Kylin 16.04 中安装了eclipse,在纠结了很久的网络问题之后,开始了eclipse的配置以便在上面运行ns3. 在官方网站上安装完 eclipse LUNA 之后 ...

  9. HDU 6162 Ch's gift(树链剖分+线段树)

    题意: 已知树上的每个节点的值和节点之间的关系建成了一棵树,现在查询节点u到节点v的最短路径上的节点值在l到r之间的节点值的和. 思路: 用树链剖分将树映射到线段树上,线段树上维护3个值,max,mi ...

  10. 51nod 1199 Money out of Thin Air(线段树+树剖分)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1199 题意: 思路:因为是一棵树,所以需要把它剖分一下再映射到线段树上, ...