C++中派生类重写基类重载函数

本文通过一个C++示例介绍了如何使用虚函数实现多态。通过基类指针调用派生类的方法,展示了多态性的核心概念。同时,也说明了非虚函数在继承中的行为。

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

#include <iostream>
using namespace std;
class Base {
public :
        virtual void print() {   //如果不加virtual,输出的全是基类
              cout << "print() in Base." << endl;
       }
        void print( int a ) {
              cout << "print(int a) in Base." << endl;
       }
        void print( string s ) {
              cout << "print(string s) in Base." << endl;
       }
};
class Derived : public Base {
public :
        void print() {
              cout << "print() in Derived." << endl;
       }
};
int main() {
        Base b;
        Derived d;
        Base * bp = &d;

       b.print();  //调用的是基类的print()
       b.print(8);
       b.print( "a" );
       bp->print();  //调用的是派生类的print()
       bp->print(10);
       bp->print( "" );
       d.print(); //调用的是派生类的print()
       
       system( "pause" );
        return 0;
}

<think>嗯,用户的问题是关于C++派生类构造函数如何初始化基类成员的。我需要先回忆一下相关的知识,然后结合提供的引用内容来组织回答。首先,根据引用[2],C++不允许在派生类的构造函数初始化列表中直接初始化基类的成员变量,因为基类成员不属于派生类。所以正确的方法应该是通过调用基类的构造函数来完成初始化。例如,在派生类的构造函数初始化列表中指定基类的构造函数,并传递相应的参数,如Derive(intm):Base(m),n(m)这样。另外,引用[3]提到,如果在派生类中显式调用基类构造函数,可能会导致重复初始化的问题,所以必须通过初始化列表的方式调用基类构造函数,而不能在派生类构造函数体内再次调用。例如,在派生类构造函数中创建基类对象指针,如Base*a =new Base(m);这样的操作只是创建一个独立的基类对象,而不是初始化继承的基类部分。 用户可能存在的误区是认为可以直接在派生类中初始化基类的成员变量,但实际上必须通过基类的构造函数。需要明确说明这一点,并给出正确的示例代码。同时,要指出常见的错误做法,比如在派生类初始化列表中直接写基类成员变量,这样会导致编译错误。然后,根据用户提供的引用[1]中的代码示例,可以展示正确的写法,并解释每个部分的作用。比如,在Derive的构造函数中,通过Base(m)来调用基类的有参构造函数,从而初始化基类的成员n。同时,派生类自己的成员n也在初始化列表中进行初始化。 可能还需要提到默认构造函数的情况,如果基类没有默认构造函数派生类必须显式调用基类的某个构造函数,否则会编译错误。这一点在引用[2]的示例中也有体现,当派生类尝试直接初始化基类成员m_name时,会导致错误。最后,总结正确的步骤:1.在派生类构造函数的初始化列表中调用基类构造函数;2.确保基类有相应的构造函数可供调用;3.避免重复初始化。同时,生成相关问题,帮助用户进一步理解,比如调用顺序、默认构造函数的影响等。</think>在C++中,派生类构造函数初始化基类成员必须通过调用基类构造函数实现,具体方法如下: ### 一、核心方法 1. **通过初始化列表调用基类构造函数** 在派生类构造函数的初始化列表中显式调用基类构造函数,例如: ```cpp Derive(int m) : Base(m), n(m) { ... } // Base(m)调用基类构造函数 ``` 这种方式会优先执行基类构造函数的初始化逻辑[^2][^3] 2. **基类构造函数选择规则** - 若未显式调用基类构造函数,编译器会自动调用基类的默认构造函数 - 若基类没有默认构造函数,则必须显式调用其他构造函数[^2] ### 二、错误示例分析 ```cpp // 错误写法:直接初始化基类成员 StatusIdle() : m_name("Idle") { } // 编译错误:m_name不是派生类的直接成员 ``` 此时编译器会报错`xx不是类xx的非静态成员或基类`[^2] ### 三、正确代码演示 ```cpp class Derive : public Base { public: // 正确方式:通过基类构造函数初始化 Derive(int m) : Base(m), n(m) { // Base(m)初始化基类成员n // 此处可以创建新的基类对象,但不会影响继承的基类部分 Base* temp = new Base(m); delete temp; } private: int n; // 派生类自身成员 }; ``` 此时输出顺序为: ``` constructor is called // 基类构造函数 get() is called // 派生类调用基类方法 Derive distructor is called Base distructor is called ``` ### 四、注意事项 1. **构造/析构顺序** 构造顺序:基类派生类 析构顺序:派生类基类[^1] 2. **成员重复问题** 若基类派生类有同名成员变量,基类成员需要通过`Base::n`方式访问
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WX Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值