类的六大默认构造函数

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(使用前将#替换为@)

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

  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 按成员序列化

    我已经实现了template
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐

  • 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