C++编译器为类自动生成拷贝构造函数的情况

2023-11-17

在一下情况中C++会为类自动生成拷贝构造函数

1.类中有虚函数

这种情况即意味着类的对象中有指向虚函数表的指针。考虑下面的情况

class A

{

private:

      int m_a;

public:

      virtual void ShowVal();
}


void A::ShowVal()

{

    printf("%d", m_a);
}

class B

{

private:

     int m_b;

public:

     void ShowVal();

}


void B::ShowVal()

{

    printf("%d", m_b);
}


int main()

{

    B b;

    b.m_b = 10;

    A a = b; //此处应该会有拷贝构造函数的调用(如果有)

    A* pa = &a;

    pa->ShowVal();

}

pa->ShowVal会报错吗?不会,但是是在编译器参与纠正的情况下,否则就错了。

因为A类的ShowVal是虚函数,也就导致A类是有虚函数表的,该表中有A类的ShowVal函数的地址,A类的ShowVal函数显示A类成员m_a

而B类继承A类后,由于B类重写了A类的ShowVal,显示B类成员m_b。因此,B类的虚函数表中存放了B类的ShowVal的地址,而不是A类的ShowVal的地址。

因此,通过简单的位拷贝模式(不提供拷贝构造函数的情况下,是默认使用位拷贝的模式),直接将B类的vptr拷贝到A类对象中。然后,当通过指针调用该A类对象的ShowVal函数的时候,就会访问到B类虚函数表中的ShowVal函数,访问到B类的m_b成员(不存在于A类对象中),然后就会出错了。

因此,编译器需要查收进行虚函数表的调整,会自动给A类生成一个拷贝构造函数,函数中重新设置A类对象的vptr,大致如下:

A::A(const A& a)

{

    this->vptr=A类的虚函数表地址;
}

那么,如果程序员显示提供了A类的构造函数的情况下会发生什么,编译器还会自动生成拷贝构造函数吗?

当A类有虚函数且程序员提供了拷贝构造函数的时候,程序员提供的拷贝构造函数肯定也不会去写重新设置vptr代码,因此,编译器会在程序员提供的拷贝构造函数中添加设置vptr的代码。


2.基类包含拷贝构造函数或者成员变量的类提供了拷贝构造函数

无论是程序员提供的拷贝构造函数还是像第一中情况下编译器自动生成的拷贝构造函数,只要基类包含了拷贝构造函数,就说明派生类中的基类部分不能直接使用位拷贝的模式进行赋值,必须调用所提供的拷贝构造函数就行构造,此时编译器会生成拷贝构造函数

B::B(const B& b)

{

    this->A::A(b);
}

类中的成员变量的类提供了构造函数的情况也是一样的

B::B(const B&b)

{

    this->m_a.A::A(b.m_a);
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++编译器为类自动生成拷贝构造函数的情况 的相关文章

  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • 未解决的包含:“cocos2d.h” - Cocos2dx

    当我在 Eclipse 中导入 cocos2dx android 项目时 我的头文件上收到此警告 Unresolved inclusion cocos2d h 为什么是这样 它实际上困扰着我 该项目可以正确编译并运行 但我希望这种情况消失
  • 如何在列表框项目之间画一条线

    我希望能够用水平线分隔列表框中的每个项目 这只是我用于绘制项目的一些代码 private void symptomsList DrawItem object sender System Windows Forms DrawItemEvent
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • 将目录压缩为单个文件的方法有哪些

    不知道怎么问 所以我会解释一下情况 我需要存储一些压缩文件 最初的想法是创建一个文件夹并存储所需数量的压缩文件 并创建一个文件来保存有关每个压缩文件的数据 但是 我不被允许创建许多文件 只能有一个 我决定创建一个压缩文件 其中包含有关进一步
  • 使用 System.Text.Json 即时格式化 JSON 流

    我有一个未缩进的 Json 字符串 例如 hash 123 id 456 我想缩进字符串并将其序列化为 JSON 文件 天真地 我可以使用缩进字符串Newtonsoft如下 using Newtonsoft Json Linq JToken
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • clang 实例化后静态成员初始化

    这样的代码可以用 GCC 编译 但 clang 3 5 失败 include
  • 从库中捕获主线程 SynchronizationContext 或 Dispatcher

    我有一个 C 库 希望能够将工作发送 发布到 主 ui 线程 如果存在 该库可供以下人员使用 一个winforms应用程序 本机应用程序 带 UI 控制台应用程序 没有 UI 在库中 我想在初始化期间捕获一些东西 Synchronizati
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • C++ 复制初始化和直接初始化,奇怪的情况

    在继续阅读本文之前 请阅读在 C 中 复制初始化和直接初始化之间有区别吗 https stackoverflow com questions 1051379 is there a difference in c between copy i
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • 如何使用 std::string 将所有出现的一个字符替换为两个字符?

    有没有一种简单的方法来替换所有出现的 in a std string with 转义 a 中的所有斜杠std string 完成此操作的最简单方法可能是boost字符串算法库 http www boost org doc libs 1 46
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐

  • HTML中所有基本标签

    1 h1 h6 为标题标签 h1 我是一个标题 h1 h2 我是一个标题 h2 h3 我是一个标题 h3 h4 我是一个标题 h4 h5 我是一个标题 h5 h6 我是一个标题 h6 网页显示效果 h1 h6 数字越大 字体越小 且独占一行
  • 无需GPU无需网络“本地部署chatGPT”(更新StableVicuna)

    想当初图像生成从DELL到stable diffusion再到苹果的移动部署过了两三年吧 聊天bot才发展几个月就可以边缘部署了 如果苹果更新silicon npu和运存翻倍 争取apple watch也能本地内置 最快ios18 mac
  • Apache网页优化压缩步骤

    Apache网页与安全优化 Apache网页优化 1 网页压缩 2 网页缓存 Apache安全优化 1 配置防盗链 2 隐藏版本信息 Apache 网页 优化概述 1 在企业中 部署Apache后只采用默认的配置参数 会引发网站很多问题 换
  • Python笔记:操作ndarray元素:访问、删除、插入

    引入 import numpy as np 在此引入一次 下面直接使用 np 访问ndarray元素 x np array 1 2 3 4 5 print print x x print print This is First Elemen
  • 《UnityAPI.Animation动画》(Yanlz+Unity+SteamVR+云技术+5G+AI+VR云游戏+Animation+AddClip+CrossFade+立钻哥哥++OK++)

    UnityAPI Animation动画 版本 作者 参与者 完成日期 备注 UnityAPI Animation V01 1 0 严立钻 2020 06 23 UnityAPI Animation动画 发布说明 UnityAPI Anim
  • Android——单选多选按钮的使用详解

    button1 Button findViewById R id button1 button2 Button findViewById R id button2 button1 setOnClickListener this button
  • java学习总结——protobuf3的语法

    本文主要讨论protobuf3在编写proto接口描述文件时的语法 下面是一个proto文件的实例 syntax proto3 import address proto package com study blog protobuf opt
  • [激光原理与应用-40]:《光电检测技术-7》- 常见光干涉仪及其应用

    目录 第1章 干涉仪概述 1 1 什么是干涉仪 1 2 基本原理 1 3 分类 1 4 应用 1 5 干涉仪的类型 第2章 常见光干涉仪 2 1 迈克尔逊干涉仪 2 2 泰曼 格林干涉仪 2 3 移相干涉测量仪 2 4 菲索共路干涉仪 第1
  • vue+webpack5:If you want to include a polyfill, you need to

    升级 vue cli 5 0 1 发现 const path require path 异常 发现默认webpack 是 提示v5区别于v4不再自动引入Polyfills 需要手动添加 按照控制台提示 1 安装path browserify
  • mysql不包含模糊查询

    包含like 不包含not like select from 数据库表 where HouseName like 江门奥园项目 and HouseName like 幢 and HouseName not like 商 不包含not in
  • jupyter修改文件目录和虚拟环境

    在我们安装完jupyter的时候 他是默认为根目录的 我们想切换到我们自己创建的文件目录中该怎么做呢 请看下面步骤 一 切换文件目录 首先 先在我们要放的目录下创建一个文件夹 如 我的为 F Jupyter 在命令行窗口中输入 jupyte
  • cocos2dx 常见的49中动作详解

    bool HelloWorld init 1 super init first if CCLayer init return false CCSprite sp CCSprite create Icon png sp gt setPosit
  • java中的类型赋值常见错误

    Java中float double long类型变量赋值添加f d L尾缀问题 添加尾缀说明 我们知道Java在变量赋值的时候 其中float double long数据类型变量 需要在赋值直接量后面分别添加f或F d或D l或L尾缀来说明
  • JAVA的可变类与不可变类

    可变类和不可变类 Mutable and Immutable Objects 的初步定义 可变类 当你获得这个类的一个实例引用时 你可以改变这个实例的内容 不可变类 当你获得这个类的一个实例引用时 你不可以改变这个实例的内容 不可变类的实例
  • Mybatis批量插入数据的三种方式分享

    转自 Mybatis批量插入数据的三种方式分享 下文笔者讲述Mybatis插入数据的方法分享 如下所示 for循环insert long start System currentTimeMillis for int i 0 i lt 100
  • 结构化思维

    我们在求职时 经常能看到岗位要求上写着 逻辑思维 系统 结构化思维 身为一个直觉的打工仔 面对未来Boss耳提面命的 能力标签 我们怎能视若无睹 逻辑思维 好理解 不就 判断 推理 嘛 可这 结构化思维 是啥 很多人就答不上来了 在理解概念
  • electron ajax路径,electron 文件及文件夹上传的问题探索

    不晓得如今electron最新版的dialog解决了这个问题没有 选择文件夹的时候没有返回文件夹里面全部的文件 而是返回了文件夹的路径 一样的在网页端是能够经过webkitDirectory获取到文件夹下面全部的文件node 我试了不少的方
  • https开头的网址是什么意思_网址是什么意思?基础知识普及

    通俗的理解网址就是常说的URL 是很多个它一起组成了数量庞大形形色色的网站 网址 Uniform Resource Locator 统一资源定位器 是计算机Web网络相关的术语 就是网页地址的意思 我们的互联网世界就是由很多的网址组成 也可
  • 2021-04-06

    开源 开源的概念 开源 一词对应英文 Open Source 最初起源于软件开发领域 因此也称为 开放源代码 对应的软件则称为开源软件 Open Source Software 除了我们熟知的开源软件以外 开源的表现形式还有开源硬件 Ope
  • C++编译器为类自动生成拷贝构造函数的情况

    在一下情况中C 会为类自动生成拷贝构造函数 1 类中有虚函数 这种情况即意味着类的对象中有指向虚函数表的指针 考虑下面的情况 class A private int m a public virtual void ShowVal void