C++中子类和父类之间的相互转化

本文通过示例代码详细介绍了C++中的多态性概念及其应用,包括编译时多态性和运行时多态性的实现方式,并探讨了基类与派生类之间的类型转换方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// EX_EXAM.cpp : 定义控制台应用程序的入口点。  
//  
#include "stdafx.h"  
#include <iostream>  
using namespace std;  

class A  
{  
public:  
    virtual void foo() { cout<<"A foo"<<endl; }  
    void pp() { cout<<"A pp"<<endl; }  
};  

class B: public A  
{  
public:  
    void foo() { cout<<"B foo"<<endl; }  
    void pp() { cout<<"B pp"<<endl; }  
    void FunctionB() { cout<<"Excute FunctionB!"<<endl; }  
};  

int _tmain(int argc, _TCHAR* argv[])  
{  
    A a;  
    B b;  
    A *pa=&b;  
    pa->foo();  
    pa->pp();  
    if (B *pb=dynamic_cast<B*>(pa))  
    {  
        cout<<"Convert from B to A successfully"<<endl;  
        (dynamic_cast<B*>(pa))->FunctionB();  
        (dynamic_cast<B*>(pa))->foo();  
        (dynamic_cast<B*>(pa))->pp();  
        (*pa).foo();  
    }  
    else  
        cout<<"Cannot convert from B to A"<<endl;  

    return 0;  
}  
class Base{
public:
    int a;
    Base()
   {
     a=15;
   }
   virtual void test(){}

   void write(){}

   };

class Derived:public Base{
  public :
  Derived()
  {
   a=19;
  }
  void test(){
   cout<<"xiao go\n"<<a<<endl;
 }

  void test1(){

 }

  void write(){

      cout<"write"<<endl;

     }
};

下面的转化是错误 的:

Base *base = new Base

Derived*derive = new  Derived

base=derive;

正确的“转化”如下:

Base *base  = new  Derived

base能实现父类中定义的所有方法,如果是虚函数,它会子类的实现,

如test()为虚函数

base.test执行结果为
xiao go 19

在执行过程中,会先调用BASE的构造函数,然后调用Derived的构造函数,因此这里的a为19,单独访问 base.a结果仍为19

在base这个变量中,除了能执行子类的虚函数和构造函数外,其它子类函数均不能执行,如base->test1()不能执行

父类转化为子类

一般情况下,父类不能向子类转化,以下特殊情况可以:

    Base *base = new Base()

    Dervie *derive =  Base *base;

   这里只调用父的类构造函数,不会调用子类的构造函数,虚函数调用父类实现而非子类的实现,其它子类增加

的函数,都可在derive中调用。

小记:

纯虚函数(方法:virtual ReturnType Function()= 0;)有纯虚函数的为抽象类,直到所有纯虚函数

都实现后,这个类才可以具体化。

C++支持两种多态性:编译时多态性,运行时多态性。
a.编译时多态性:通过重载函数和运算符重载实现。
b运行时多态性:通过虚函数和继承实现。

Base * pB1 = new Base;
Base * pB2 = new Derived;
子到父自动类型提升。。不需要强转。。

Base *A =new Derived; //Derived->Base.

父到子才需要强制类型转换

Derived * D1 = dynamic_cast<Derived * > (pB1);
<think>好的,我现在要回答用户关于C++中子如何继承重写父类函数的问题。首先,我需要回顾一下用户提供的引用内容,确保答案准确。 根据引用[2],C++中如果父类的函数是虚函数,子类重写时会覆盖父类的函数;如果非虚函数,子类同名函数会隐藏父类的函数,但可以通过作用域运算符显式调用。引用[3]提到,如果子类没有重写父类的成员函数,那么子类会继承并使用父类的函数,且它们在代码段共享同一内存。 接下来,我需要整理继承重写的步骤。首先,子类继承父类时使用public继承,然后在子类中声明同名函数。对于虚函数,需要使用override关键字(C++11之后),并确保函数签名一致。如果父类函数不是虚函数,子类可以通过作用域运算符调用父类版本。 用户可能需要示例代码来理解具体实现。需要给出一个父类子类的例子,展示继承重写的情况,以及如何显式调用父类函数。同时,要区分虚函数非虚函数的处理方式。 此外,需要说明内存中的情况,如引用[3]所述,未重写的函数在代码段共享内存。这可能涉及函数指针虚函数表的概念,但用户可能不需要太深入,保持简洁即可。 最后,生成相关问题时要围绕继承、虚函数、作用域调用等方面,帮助用户进一步学习。比如,虚函数的作用、构造函数继承等。 检查是否有遗漏点,比如构造函数继承的问题,引用[1]提到子类通过初始化列表调用父类构造函数,但用户的问题是函数继承,可能不需要深入构造函数部分,但可以简要提及。 确保语言口语化,避免术语堆砌,结构清晰,分点说明。代码示例正确,符合C++标准,比如使用override关键字,正确的作用域解析。</think>在C++中,子类继承重写父类函数的过程涉及以下几个关键点: ### 一、基础继承规则 1. **公开继承**:使用`class Child : public Parent`语法实现父类成员的完全继承 2. **函数可见性**: - 父类的非虚函数会被子类继承,但可能被隐藏(如果子类有同名函数) - 父类的虚函数(`virtual`修饰)允许子类进行覆盖(override) ### 二、函数重写实现方法 ```cpp class Parent { public: virtual void func() { // 虚函数声明 cout << "Parent function" << endl; } }; class Child : public Parent { public: void func() override { // 使用override确保正确重写 cout << "Child override" << endl; } }; ``` *输出结果:* ``` Child override ``` ### 三、非虚函数的处理 ```cpp class Parent { public: void nonVirtualFunc() { cout << "Parent non-virtual" << endl; } }; class Child : public Parent { public: void nonVirtualFunc() { // 隐藏父类同名函数 cout << "Child new function" << endl; } }; // 调用示例 Child c; c.nonVirtualFunc(); // 输出Child版本 c.Parent::nonVirtualFunc(); // 显式调用父类版本[^2] ``` ### 四、内存机制 1. **未重写函数**:父类函数代码段内存被子类共享,不会产生副本[^3] 2. **虚函数覆盖**:通过虚函数表(vtable)实现动态绑定,子类虚函数会覆盖父类在虚表中的对应项[^2] ### 五、注意事项 1. **函数签名一致性**:重写虚函数必须保持参数列表返回型一致(协变返回型除外) 2. **访问权限控制**:子类可以修改继承函数的访问权限(通过using声明) 3. **构造函数调用**:子类构造函数必须通过初始化列表调用父类构造函数[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值