You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++派生类拷贝构造与赋值运算符未调用基类对应方法问题

C++继承场景特殊成员函数行为测试

测试代码

头文件 10.h

#ifndef header
#define header

struct base
{
    private:
        int p,q;
    public:
        base();
        base(const base&);              
        base operator=(const base&);    
        ~base();
};

struct der: public base
{
    private:    
        int x,y;
    public:
        
        der();
        der(const der&);
        der operator=(const der&);
        ~der();
}; 
#endif

实现文件 10.cpp

#include"10.h"
#include<iostream>

base::base()
{
    std::cout<<"base ctor- 0 arg\n";
    p=0; q=0;
}
base::base(const base &b)
{
    std::cout<<"base copy ctor\n";
    p=b.p;
    q=b.q;
}
base base::operator=(const base &b)
{
    std::cout<<"base overloaded=operator\n";
    p=b.p;
    q=b.q;
    return *this;
}
base::~base()
{
    std::cout<<"base dctor\n";
}


der::der()
{
    std::cout<<"derived ctor- 0 arg\n";
}
der::der(const der &d)
{
    std::cout<<"derived copy ctor\n";
    x=d.x;
    y=d.y;
    
}
der der::operator=(const der &d)
{
    std::cout<<"derived overloaded operator\n";
    x=d.x;
    y=d.y;
    return *this;
    
}
der::~der()
{
    std::cout<<"derived dctor\n";
}

主函数代码

#include"10.h"
#include<iostream>
int main()
{
    der d1,d2;
    std::cout<<"\n";
    
    d2=d1;
    std::cout<<"\n";
    
    der d3=d1;
    std::cout<<"\n";
}

运行输出

base ctor- 0 arg
derived ctor- 0 arg
base ctor- 0 arg
derived ctor- 0 arg

derived overloaded operator
base ctor- 0 arg
derived copy ctor
derived dctor
base dctor

base ctor- 0 arg
derived copy ctor

derived dctor
base dctor
derived dctor
base dctor
derived dctor
base dctor

问题解答

问题1:未主动创建基类对象,为何调用派生类拷贝构造函数和重载赋值运算符时,会触发基类无参构造函数?

  • 派生类对象本身内置了基类子对象,任何派生类对象构造时,一定会先构造基类部分,不管你是否显式声明,这个行为是强制的。
  • 你自己实现了派生类的拷贝构造函数,但没有在初始化列表显式指定调用基类的拷贝构造函数,编译器就会默认插入基类无参构造函数来初始化基类子对象。
  • 另外你的派生类赋值运算符是按值返回der类型,执行return *this时需要构造一个临时的der对象作为返回值,这个临时对象的构造会调用派生类拷贝构造,又会再次触发基类无参构造,输出里赋值逻辑对应的base ctor就是这个来源。

问题2:派生类的重载赋值运算符为何没有自动调用基类对应的重载赋值运算符?

C++标准明确规则:只要你显式自定义了派生类的赋值运算符重载,编译器不会自动帮你插入基类赋值的调用逻辑,基类部分的赋值需要你手动显式调用,比如在派生类赋值函数开头加base::operator=(d);才会触发基类赋值逻辑,否则只会执行你写的派生类自有成员的赋值代码,基类成员不会被赋值。

问题3:派生类的拷贝构造函数为何没有自动调用基类对应的拷贝构造函数?

只有编译器默认生成的派生类拷贝构造函数,才会自动调用基类的拷贝构造函数。一旦你显式自定义了派生类的拷贝构造函数,你就需要自己负责基类子对象的初始化逻辑:如果你没有在派生类拷贝构造的初始化列表指定调用基类拷贝构造,编译器只会默认调用基类无参构造,不会自动调用基类拷贝构造。


内容的提问来源于stack exchange,提问作者Abhishek Mane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 09:00:05