类的六大默认构造函数

2023-11-15

缺省的构造函数和析构函数,等于放弃了自己初始化和清除的机会;缺省的拷贝构造和缺省的赋值函数,采用“位拷贝和值拷贝”。若类中出现指针时,这两个函数出错。

class String
{
public:
String(const char *str = NULL);//构造
~String();//析构
String (const String &s);//拷贝构造
String& operator=(const String &s);//赋值
String* operator&();//普通引用方法
String* operator&()const;//常引用方法
private:
char* m_str;
};

构造函数与析构函数

构造函数和析构函数表明了一个对象的由生到死的过程。一个对象只能调用一次构造方法,一个类有且只有一个析构方法。

构造函数作用:
1、实例化对象 2、对对象成员进行初始化 3、强制类型转化(通过中间桥梁实现)

#

类的数据成员的初始化方式(二者效率不同)
1、初始化列表方式
2、函数体内赋值
3、类的const 常量只能在初始化列表内初始化,不能在函数体内进行赋值。

#

构造顺序
1、遇到对象自动调用其构造方法,如若有继承关系时,则先调用父类的构造方法;当主函数中构造对象完成时自动调用析构函数。
2、先构造者后析构,因为构造函数中,对象是通过堆栈的方式进行存储的,同理 析构时按照出栈的顺序。

成员对象初始化的次序完全不受他们在初始化列表中的次序,只与成员对象在类中的声明次序有关。

#include<iostream>
using namespace std;

class Test
{
public:
    Test()
    {
    cout<<this<<endl;//6c
    }
    Test(int d,int num):number(num),data(d)
    {
        cout<<this<<endl;//64
        cout<<"data-->"<<this->data<<endl;
        cout<<"number-->"<<this->number<<endl;
    }
    ~Test()
    {
        cout<<"~Test()"<<this<<endl;
    }
private:
    int data;
    int number;
};

void main()
{
    Test t;
    Test t2(1,2);
}

这里写图片描述

强制类型转化

#include<iostream>
using namespace std;
class Test
{
public:
    Test()
    {
        cout<<"Test()"<<this<<endl;
    }
    Test(int d):data(d)
    {
        cout<<"Test()"<<this->data<<endl;
    }
    /*int GetData()const
    {
        return data;
    }
    */
    operator int()
    {
        return data;
    }

    ~Test()
    {
        cout<<"Free Test()"<<this<<endl;
    }
private:
    int data;
};
void main()
{
    //Test t1(); 声明函数,能编译、能运行,但是是错误的
    Test t(1);
     t =100;//100通过构建函数构造中间零时对象,对象给对象赋值
     //若构造函数前面加上explicit关键字时,则赋值时必须显示调用即  t =(Test) 100;    
     int value;
    //通过公有方法获取data值
    //value = t.GetData();
    //调用operator int()方法,将对象类型强制转换为值类型
    value = t;

}

这里写图片描述

构造函数,有两种方式:

1、定义无参构造函数 2、定义所用带默认值的构造函数 且 二者方式只能用一种。一个类只能有一个带默认值的构造函数。不然程序产生二义性。当带默认值的参数,没有初始化时,则产生随机值。

#include<iostream>
using namespace std;

class Test
{
public:
    //无参构造
    Test()
    {}
    Test(int d):data(d)
    {
        cout<<data<<endl;
    }
    //带默认值的构造
    /*
    Test(int d=0)
    {
        data = d;
        cout<<data<<endl;
    }
    */
private:
    int data;
};
void main()
{
    Test t(2);
}

拷贝构造与赋值函数

拷贝构造函数:用一个已有对象去初始化一个新的对象。

产生拷贝构造的条件:

1、用已有对象去初始化新的对象
2、函数参数类型传递
3、函数返回值类型的对象。

include<iostream>
using namespace std;
include<vld.h>
class Test
{
public:
    Test()
    {}
    Test(int d):data(d)
    {}
    void print()
    {
        cout<<data<<endl;
    }
    //不用引用,自己解释自己会产生循环递归
    Test(const Test &other)
    {
        data = other.data;
    }
    ~Test()
    {
        cout<<"~Test()"<<endl;
    }
private:
    int data;
};
void fun(Test s1)
{
    cout<<"fun()"<<endl;
}
Test fn()
{
    Test s2(1);
    //返回s2之前会产生无名的临时对象,即用s2去构造对象 因此调用拷贝构造函数
    return s2;
}
void main()
{
    Test t(2);
    //两者一样
    //Test t1(t);
    Test t1= t;
    t.print();
    t1.print();
    //对象作为函数参数
    fun(t1);
    //对象作为函数的返回值
    t=fn();
}

这里写图片描述

return 返回时,实际调用了拷贝构造函数构造了一个无名的临时对象

int  Sum(int a,int b)
{
    return sum=a+b;
    //返回的不是sum,sum在离开作用域时,已经被释放;会产生一个临时无名对象,并将sum 值传给该对象。
}
void main()
{
    int val=Sum(1,2);
}

赋值

赋值相当于a对象的成员参数,给b的成员参数赋值。
1、是否把返回值的类型声明为该类型的引用。
2、是否把传入的参数声明为常量引用。
3、是否释放自己已有空间。
4、是否判断传入的参数和当前的实例(*this)是不是一个实例。

#

#include<iostream>
using namespace std;
#include<vld.h>
class Test
{
public:
    Test(int d=0):data(d)
    {}
    void print()
    {
        cout<<data<<endl;
    }
    Test(const Test &other)
    {
        data = other.data;
    }
    /*
    1.const:表明对象的数据成员在赋值过程中,不被修改
    2.&s:减少调用一次拷贝构造函数,也提高效率,在程序中,当对象不受函数作用域的影响时,可以使用&
    3.Test 为了是连续对象间赋值t1=t2=t3;
    4.在返回类的对象*this时,会产生临时对象调用拷贝构造函数。&为了不构造临时对象,减少调用拷贝构造
    t1.operator=(t2.operator=(t3))
    */
    Test& operator=( const Test &s)
    {
        if(this != &s)
        {
            data = s.data;
        }
        //返回当前对象
        return *this;
    }
    ~Test()
    {
        cout<<"~Test()"<<endl;
    }
private:
    int data;
};

void main()
{
    Test t(10);
    Test t1(t);
    Test t2;
    t2 = t1;
    //t2.operator=(t1)
    //t2.operator=(&t2,t1)
    //下面的const用来说明当前对象不允许修改
    //Test& operator(Test *const this,const  Test &s )
}

普通引用方法与常引用方法

#include<iostream>
using namespace std;
#include<vld.h>

class String
{
public:
    String(char *str=NULL)
    {
    //构造的对象为NULL时,String a(""|NULL|0)和String a()不一样
        if(str == NULL)
        {
            m_str = new char[1];
            *m_str = '\0';
        }
        else
        {   
            m_str = new char[strlen(str)+1];
            strcpy(m_str,str);
        }
    }
    //深拷贝
    String(const String &s)
    {
         m_str = new char[strlen(s.m_str)+1];
        strcpy(m_str,s.m_str);
    }
    //深赋值
    String& operator=(const String &other)
    {
        if(this != &other)
        {
        String tmp=other;
        char *pstr=m_str;
        m_str= tmp.m_str;
        tmp.m_str = pstr;
        }
        return *this;

    }
    //普通引用方法
    String* operator&()
    {
        return this;
    }
    //常方法
    const String* operator&()const
    {
        return this;
    }
    ~String()
    {
        delete []m_str;
        m_str = NULL;
    }
private:
    char *m_str;
};
void main()
{
    String s("123");
    String s1=s;
    String s2;
    s2=s1;
    String *p =&s1;
    const String s3("Hello");
    const String *q =&s3;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类的六大默认构造函数 的相关文章

  • 比较 LINQ to SQL 中的两个日期

    我有一个数据库 其中有一个名为会议的表 会议日期使用以下格式存储在此表中 May 2nd 2011 例如 格式为5 2 2011 我的要求是获取两个日期 例如 2011 年 4 月 25 日和 2011 年 5 月 2 日 之间的会议 并编
  • 计算复杂数组的abs()值的最快方法

    我想计算 C 或 C 中复杂数组元素的绝对值 最简单的方法是 for int i 0 i lt N i b i cabs a i 但对于大向量来说 速度会很慢 有没有办法加快速度 例如使用并行化 语言可以是 C 或 C 鉴于所有循环迭代都是
  • & 运算符的含义是什么?

    在下面的代码中 Expression
  • 通过用于 Symbol 条码扫描仪 DS4208 的 SNAPI.dll API 捕获图像

    我想通过 SNAPI API 从 Symbol 目前为 Zebra 条形码扫描仪 DS4208 型号 我们还使用 Zebra 的另一个但兼容的型号 捕获图像 条形码捕获 识别效果很好 但看起来像SnapiDLL SNAPI SnapShot
  • boost::asio::io_service 是否保留处理程序的顺序?

    Does boost asio io service http www boost org doc libs release doc html boost asio reference io service html保证处理程序的调用顺序与
  • 以编程方式运行 T4 文本模板

    有没有一种方法可以通过代码以编程方式运行 T4 文本模板 我正在制作一种自定义域特定语言 我希望相关的文本模板在用户每次保存时运行 目前 这就是我在 DSL 模型中所做的事情 protected override void OnDocume
  • 函数指针上的未知类型 F TYPE

    include
  • 如何在Azure功能中添加razor视图文件?

    我正在创建一个应用程序 它是 azure 函数项目 我想在该项目中使用 Razor 视图 我应该在 azure 函数中使用任何模板引擎吗 得益于一些方面的进步剃刀之光项目 https github com toddams RazorLigh
  • ASP.NET中如何访问除wwwroot以外的位置

    我可以使用访问服务器的物理位置Server MapPath 这给了我内部的物理路径wwwroot文件夹 我想将一些数据保存到同一服务器的另一个驱动器中D 驾驶 我想我无法获取以下位置的物理位置D 驾驶使用Server MapPath因为它位
  • 如何使用 ProtoGen 从 proto 文件生成结构

    我们一直在使用 protobuf net ProtoGen 从 proto 文件生成 C cs 文件 我们希望代替类来生成结构 例如 DataContract public struct Entity1 ProtoMember 1 publ
  • 将授权标头添加到 Web 参考

    我正在尝试向客户端的网络服务发出请求 我不知道客户端的底层平台 我使用 添加 Web 引用 在 Visual Studio 2010 中使用了客户端的 WSDL 并生成了我的代理类 称为 ContactService 我现在需要将如下所示的
  • 执行存储过程时 ExecuteNonQuery() 返回 -1

    我正在尝试在 Visual Studio 中执行存储过程 下面给出 CREATE PROCEDURE dbo addStudent stuName varchar 50 address varchar 100 tel varchar 15
  • 为什么 httpRuntime targetFramework="4.5" 禁止抓取 .ASPXAUTH cookie?

    当我的 web config 具有以下 httpRuntime 时 我的控制器无法获取 cookie ASPXAUTH 它似乎能够获取任何其他 cookie 无论带或不带句点前缀 如果我删除下面的行 它就可以正常工作
  • Nuget - 对象引用未设置为对象的实例

    我在 vs 2015 中遇到了 nuget 包管理器的问题 像Unity这样的一些包已经安装没有问题了 某些软件包 例如 EF 在安装时出现问题 像 Automapper 这样的一些软件包也有同样的问题 但是当我安装这个软件包的另一个版本时
  • C 中的链表数组:初始化和插入?

    我需要创建一个链表数组 如图所示 这就是我到目前为止所做的 typedef struct Node int data struct Node next Node int main void Node link 5 for int q 0 q
  • 使用 _Alignas 进行结构成员对齐

    我想知道以下问题 是新的吗 Alignas结盟 C11 中的说明符适用于结构成员吗 我一直假设这么多 但彻底阅读了 N1570 公开草案似乎表明对齐说明符不能 出现在一个说明符限定符列表 这就是我所期望的 如果得到支持的话 我已经读过几遍语
  • #define 内存地址声明

    这个 define 语句有什么作用 它用于定义内存地址 但我不明白 uint32 t 部分 define GPxDAT uint32 t 0x6FC0 通常用于访问映射到地址空间的硬件寄存器 或者一些特定的内存地址 硬件寄存器应定义为vol
  • 使用非字符串作为字符串(而不是自动使用 ToString)时如何显示错误?

    建议的重复确实是一个类似的问题 然而 答案只涵盖一种选择 禁用 ToString 本身 还有其他可能的解决方案 例如让 Visual Studio 警告我 或者不调用 ToString 仔细阅读那里的答案 他认为is调用 只是解释说没有办法
  • 使用 MVC5、Ajax、C# 和 MSSQL Server 级联 DropdownList

    我对来自 Windows 窗体和三层架构的 MVC 非常陌生 我试图找出使用从数据库填充的级联下拉列表 DDL 我使用 MS SQL Server 2012 VS 2013 目前我正在研究用户调查问卷 用户可以从 DDL 的多个答案中进行选
  • 如何使用 Ioc Unity 注入依赖属性

    我有以下课程 public interface IServiceA string MethodA1 public interface IServiceB string MethodB1 public class ServiceA IServ

随机推荐

  • Python操作ElasticSearch条件查询

    一 基本操作 1 列表元素之一查询 如 terminalType pc mobile 正确用法 GET http 0 0 0 0 8200 amis action data data search size 10000 查询条件 Ps 数组
  • 【转】内存数据库、关系型数据库和非关系型数据库

    内存数据库 关系型数据库和非关系型数据库 一 内存数据库 关系型数据库和非关系型数据库 1 个人观点 二 内存数据库 Redis MongoDb SQLite Oracle等 三 Raft分布式协议 四 Redis出现宕机 如何保证数据不丢
  • python极限学习机ELM做一个简单的分类

    最近事太多 只能下班后挤时间学习 缓慢更新 华丽的分割线 极限学习机是我们实验室的元老了 是一种单隐层前馈神经网络 SLFN 学习算法 这种算法只需要设置网络的隐层节点个数 执行过程中不需要调整网络的输入权值以及隐元的偏置 并且产生唯一的最
  • 哈希表查找——成功和不成功时的平均查找长度

    哈希表查找 成功和不成功时的平均查找长度 以下求解过程是按照 计算机统考的计算方法 不同的老师 教材在 处理冲突 上可能会有不同的方法 所以最主要的是掌握原理即可 对于考研的朋友最好掌握统考真题的解题方法 题目 例子 2010年全国硕士研究
  • 13.Python列索引值

    1 基础Python vi 6csv reader column by index py encoding utf 8 usr bin env python3 import csv import sys input file sys arg
  • mmsegmentation V0.27.0环境搭建(一)

    1 官网 2 兼容的MMSegmentation和MMCV版本如下 请安装正确版本的MMCV 以避免安装问题 3 Installation Linux系统环境安装 1 创建虚拟环境并安装pytorch Step 1 Create a con
  • ProtoBuf-反射原理与使用

    文章目录 前言 相关应用场景 一 ProtoBuf 反射原理概述 1 获取message和service的属性和方法 1 1 使用protoc将proto文件生成 h和 cc文件 1 2 只使用proto文件 不使用protoc进行编译 1
  • Gvim高级操作006--verilog例化代码对齐

    Gvim高级操作006 verilog例化代码对齐 Gvim如果没有安装对齐插件的情况下 无法通过快捷操作实现verilog例化代码对齐 但是可以通过正则表达式匹配插入空格实现代码对齐 基本原理是 删除空格 点号 和信号之间不能有空格 左括
  • FastCFS binlog机制简介

    FastCFS binlog机制简介 本篇文章转载于 FastCFS 作者 余庆 大佬的 FastDFS分享与交流 公众号 FastCFS 采用经典的 Master Slave 结构及数据同步复制的做法 如果 slave 在线 master
  • JDK 各版本汇总表

    提示 写完文章后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 一 JDK各版本 时间表 二 JDK各版本 新特性 JDK4 JDK5 JDK6 JDK7 JDK8 JDK9 JDK10 JDK11 JDK12 JDK13 JD
  • Android 蓝牙打印机Service Intent must be explicit

    安卓htc m8手机 链接蓝牙热敏打印机 佳博gp5890xIII 提示 Service Intent must be explicit 根据打印机官方提供的demo 修改为 private void connection conn new
  • 【基础知识】智能指针shared_ptr、weak_ptr、unique_ptr

    目录 一 shared ptr 共享智能指针 1 初始化 1 use count 成员函数 2 构造函数初始化 3 拷贝构造和移动构造函数初始化 4 std make shared 初始化 5 reset方法初始化 2 获取原始指针 二 w
  • 2019/5/13 基于模型的强化学习方法

    注 论文写作四项工作 工作一 查阅100篇 挑选30篇 核心参考3 5篇 看懂 一篇 工作二 提出难点问题 提出新概念 例 多光谱 注意力机制 工作三 修改算法 网络结构 损失函数 步数 工作四 写写写 改改改 图片精修 丰富实验 首句中心
  • ARM64撬开逆向大门

    图片
  • QML和QWidget混合开发(初探)

    为什么要搞混合开发 Qml已经越来越成为Qt开发的主流 相比与QWidget的界面开发更快 也更容易上手 实现效果上也更好 但老旧项目都是QWidget的框架 大家不可能一次性的把QWidget项目界面全部换成qml 这时候我们可以将新开发
  • python条件运算符_Python中的条件运算符

    python条件运算符 如果条件运算符 if else conditional operator Just like other programming languages Python also provides the feature
  • Spring全家桶

    Spring Spring的架构体系 spring是一个基于java语言写的一个轻量级的一站式解决方案框架 它的最底层是核心容器 在核心容器上面提供了AOP这些中间层技术 然后再往上就可以去集成别人的技术 比如像Dao层的MyBatis J
  • 银河麒麟V10 wireshark安装说明(断网离线)

    下载离线安装包 链接 https pan baidu com s 11QFRmCGlIJrJaiKcHh9Hag pwd u9wv 提取码 u9wv 安装步骤 tar zxvf wireshark tar gz cd wireshark s
  • python连接wss走自己的代理

    我开了一个vpn 然后用py写wss连接 怎么才能让他这个连接走我系统代理呢 vpn 开9090端口 set https proxy socks5 127 0 0 1 9090 set http proxy socks5 127 0 0 1
  • 类的六大默认构造函数

    缺省的构造函数和析构函数 等于放弃了自己初始化和清除的机会 缺省的拷贝构造和缺省的赋值函数 采用 位拷贝和值拷贝 若类中出现指针时 这两个函数出错 class String public String const char str NULL