C++基础三(构造函数,形参默认值,函数重载,单例模式,析构函数,内联函数,拷贝构造函数)

    C++有六个默认函数,分别是:   

 1、默认构造函数;   

 2、默认拷贝构造函数;     

3、默认析构函数;   

 4、赋值运算符;   

 5、取址运算符;     

6、取址运算符const;

构造函数

构造函数(初始化类成员变量):
    1、属于类的成员函数之一
    2、构造函数没有返回类型
    3、构造函数的函数名必须与类名相同
    4、构造函数不允许手动调用(不能通过类对象调用)
    5、构造函数在类对象创建时会被自动调用
    6、如果没有显示声明构造函数,系统会生成一个默认的构造函数
    7、如果显示声明了构造函数,那么默认构造函数将不会在被创建
    8、构造函数不被设置为静态成员函数
    9、构造函数的函数首部之前或函数首部之后不能用const修饰
    10、new一个类指针也会触发构造函数的调用, malloc不会
    11、构造函数通过函数重载的方式也可以拥有多个
    12、构造函数也可以使用形参默认值
    13、构造函数可以是private的

#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

#if 0 // 构造函数

class Node
{
    public:
        //Node();
        Node(int n = 0, char* ptr = NULL, float score = 1.3f);
        // static Node(); // error
        // Node() const;  // error
        // const Node();  // error

    private:
        int m_num;
        char* m_ptr;
        float m_fscore;
};


// 类成员变量初始化方式2(常用这种方式)
// 通常普通类成员变量都需要在构造函数上进行初始化。
//Node::Node() 
//    : m_num(111),
//      m_ptr(NULL),
//      m_fscore(0.0) 
//{
//    // 类成员变量初始化方式1:
//    //m_num = 10;
//
//    cout << "construct: " << m_num << endl;
//}

Node::Node(int n, char* ptr, float score)
    : m_num(n),
      m_ptr(NULL),
      m_fscore(score)
{
    m_ptr = new char[100];

    strcpy(m_ptr, ptr);

    cout << m_num << " : " << m_ptr << " : " << m_fscore << endl;
}

int main(int argc,char *argv[])
{
    // 触发构造函数调用
    Node n;
    // n.Node(); // error


    Node n1(1, "st", 1.1);

    // 触发构造函数调用
    //Node* n1 = new Node;

    // 不会触发构造函数调用
    //Node* n2 = (Node*)malloc(sizeof(Node));

    return 0;
}
#endif


形参默认值

形参默认值:
    1、给函数的形参一个默认的值。
    2、如果我们在调用函数时指定实参的值,则形参的默认值不生效。
    3、如果调用函数时没有给实参值,形参默认值才会生效。
    4、形参默认值只需要在函数声明时写出来即可。
       如果有函数声明的前提下, 在函数定义时写形参默认值会报错。
    5、形参默认值只能出现在形参列表的最右边(后边)。

#if 0 // 形参默认值

class Node
{
    public:
        // 形参默认值
        void fun(int x, int y, int num = 12, int z = 1);
        void display();

    private:
        int m_num;
};

void Node::fun(int x, int y, int num, int z)
{
    m_num = num;
}

void Node::display()
{
    cout << m_num << endl;
}

int main()
{
    Node n;
    n.fun(1, 2, 12345);
    n.display();

    n.fun(1, 2);
    n.display();

    return 0;
}

#endif

函数重载

函数重载:
    1、在C++允许出现同名函数
      (1) 形参个数不同
      (2) 形参类型不同
      (3) 形参顺序不同: 前提类型不同
      (4) 函数的返回类型不影响
    2、函数重载时,调用函数是在编译期间就确定了具体调用对象,
       因为我们将函数重载称之为静态联编
    3、重载函数调用时,不要出现二义性问题

#if 0 // 函数重载
#include <stdio.h>

void fun(int x, float y)
{
    cout << "fun(int x, float y)" << endl;
}

void fun(int x, int y)
{
    cout << "void fun(int x, int y)" << endl;
}

void fun(int x, int y, int z = 0)
{
    cout << "void fun(int x, int y, int z = 0)" << endl;
}

void fun()
{
    cout << "fun()" << endl;
}

void fun(float x, int y)
{
    cout << "fun(float x, int y)" << endl;
}

int main()
{   
    fun(1.1f, 12);
    fun(12, 1.3f);

    fun(1, 2, 3);
    fun(1, 2); // error: 出现了二义性

    return 0;
}

#endif

单例模式

#if 1 // 设计模式:单例模式

class Node
{
    public:
        static Node* getInstance();

    private:
        Node();

    private:
        static Node* m_ptr;
};

Node* Node::m_ptr = NULL;

Node::Node()
{
    cout << "construst" << endl;
}

Node* Node::getInstance()
{
    if (m_ptr == NULL)
    {
        m_ptr = new Node;
    }

    return m_ptr;
}

int main()
{
    //Node n; // error: ‘Node::Node()’ is private
    //Node* n1 = new Node; // error: ‘Node::Node()’ is private
    //Node* n2 = (Node*)malloc(sizeof(Node)); // 可以

    Node* n = Node::getInstance();
    cout << n << endl; 

    Node* n1 = Node::getInstance();
    cout << n1 << endl; 

    Node* n2 = Node::getInstance();
    cout << n2 << endl; 

    Node* n3 = Node::getInstance();
    cout << n3 << endl; 

    Node* n4 = Node::getInstance();
    cout << n4 << endl; 
    return 0;
}

析构函数

析构函数:
    1、类对象或类指针销毁时析构函数会被自动调用
    2、如果没有显示声明析构函数,则系统会生成一个默认的析构函数
    3、如果显示声明了析构函数,则不会在生成默认的析构函数
    4、析构函数没有返回类型,没有形参列表,且函数名与类名相同
    5、析构函数只有一个,不能重载
    6、析构函数不能设置为私有的
    7、析构函数可以手动调用,但不允许
    8、如果类对象的作用域相同,那么在销毁时析构函数的执行顺序与构造相反。

#include <iostream>
using namespace std;

class Node
{
    public:
        Node();
        Node(int n);
        ~Node();
        //~Node(int num = 0); // error: destructors may not have parameters
   
        void fun();
        inline void fun1()
        {
            cout << "fun1" << endl;
        }

    private:
        int* m_ptr;
};

Node::Node()
    : m_ptr(NULL)
{
    if (m_ptr == NULL)
    {
        m_ptr = new int[100];
    }

    cout << "construct" << endl;
}

Node::Node(int n)
    : m_ptr(NULL)
{
    if (m_ptr == NULL)
    {
        m_ptr = new int[100];
    }

    *m_ptr = n;

    cout << *m_ptr << "construct"  << endl;
}

void Node::fun()
{
    Node n(8);
    cout << "fun" << endl;
}

Node::~Node()
{
    cout << *m_ptr << "destruct" << endl;

    if (m_ptr != NULL)
    {
        delete[] m_ptr;
        m_ptr = NULL;
    }
}

int main(int argc,char *argv[])
{
    Node n0(0), n2(2);

    n0.fun();
    
    Node n3(3), n4(4), n5(5);
    //Node* n1 = new Node;
    //delete n1;

    // n0.~Node(); // 可以但不允许

    cout << "aaa" << endl;

    return 0;
}

内联函数

内联函数:
    1、在普通类成员函数声明之前添加 inline 关键字
    2、内联函数通常函数定义和函数声明都写在类声明中
    3、内联函数的函数体中不能出现复杂结构
    4、函数函数体中的代码一般3行左右
    5、通常被频繁调用的函数才需要设置为内联函数
    6、内联函数是进行函数逻辑的替换,其不进行真正的函数调用,减少系统开销
    7、系统会自动判断当前函数是否是内联函数,也会自动判别是否需要使用内联。

内联函数与c的宏函数有什么不同

1、宏函数是在编译阶段处理,是纯字符串替换; 内联函数是运行阶段处理,是函数逻辑替换; 2、宏函数无法调试;  内 联函数可以调试;

3、宏函数没有返回值;   内联函数有返回值;

4、宏函数不能访问类成员; 内联函数可以访问类成员;

拷贝构造函数

拷贝构造函数:
    1、拷贝构造函数属于构造函数的重载
    2、拷贝构造函数,要求形参中有一个当前类的类对象的引用
    3、如果没有显示声明拷贝构造函数,系统会生成一个默认的拷贝构造函数
    4、如果显示声明了拷贝构造函数,那么默认拷贝构造函数将不会在被创建
    5、当使用一个老对象去构造一个新对象时会调用拷贝构造函数
        (1) 用一个老对象构造一个新对象,或者新对象赋给老对象。
        (2) 当函数的形参是一个非引用的类对象时,实参到形参传递时。
        (3) 函数返回一个非引用的类对象时。
    6、如果没有显示声明和定义拷贝构造函数时,类中的非指针类成员的值是可以被拷贝的。
       默认拷贝构造函数负责执行了值的拷贝。
    7、如果显示声明和定义拷贝构造函数后,类中的所有成员变量都需要我们手动进行拷贝。
    8、拷贝分为浅拷贝和深拷贝,默认拷贝构造函数只能进行浅拷贝。
    9、浅拷贝只进行值的拷贝,深拷贝还会执行内存拷贝。

#include <iostream>
using namespace std;


class Node
{
    public:
        Node();
        Node(const Node& n);
        ~Node();

    private:
        int m_num;
        int* m_ptr;
};

Node::Node()
    : m_num(12),
      m_ptr(NULL)
{
    if (m_ptr == NULL)
    {
        m_ptr = new int[100];
    }

    *m_ptr = 123;

    cout << "construct" << m_num << " -- " << *m_ptr << endl;
}

Node::Node(const Node& n)
    : m_num(0)
{
    if (m_ptr == NULL)
    {
        m_ptr = new int[100];
    }

    *m_ptr = *(n.m_ptr);

    cout << "copy construct" << m_num << " -- " << *m_ptr << endl;
}

Node::~Node()
{
    cout << "destruct: " << m_num << " -- " << *m_ptr << " : " << m_ptr << endl;

    if (m_ptr != NULL)
    {
        delete[] m_ptr;
        m_ptr = NULL;
    }
}

int main(int argc,char *argv[])
{
    Node n1;
    Node n2(n1);

    return 0;
}


#include <iostream>
using namespace std;


class Node
{
    public:
        Node();
        Node(const Node& n);
        ~Node();

        Node fun(Node n);

    private:
        int m_num;
};

Node::Node()
    : m_num(12)
{
    cout << "construct: " << m_num << endl;
}

Node::Node(const Node& n)
    : m_num(0)
{
    cout << "copy construct: " << m_num << endl;
}

Node Node::fun(Node n)
{
    n.m_num = 111;
    cout << "fun" << endl;

    return n;
}

Node::~Node()
{
    cout << "destruct: " << m_num << endl;
}

int main(int argc,char *argv[])
{
    Node n1;
    //Node n2(n1);
    //Node n3 = n1;
    
    //Node n3 = n1.fun(n1);
    
    // 如果有返回,但我们没有接收的时候,系统会自动生成一个临时(隐藏)对象
    // 当前的临时(隐藏)对象的生存周期是从return开始,当前函数调用语句执行完毕结束。
    n1.fun(n1);

    cout << "---------" << endl;

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/906579.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

「DSA」C++排序算法 之 选择排序_Selection Sort_O(n²)

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

完美洗牌的秘密(十三)——(反)完美洗牌第二定理的应用(16张的Anti faro周期魔术)...

早点关注我&#xff0c;精彩不错过&#xff01; 在前面的文章中&#xff0c;我们介绍了&#xff08;反&#xff09;完美洗牌定理的应用的海量魔术&#xff0c;详情请戳&#xff1a; 完美洗牌的秘密&#xff08;十二&#xff09;——反完美洗牌定理的应用扩展&#xff08;三叠发…

TOEIC 词汇专题:旅游计划篇

TOEIC 词汇专题&#xff1a;旅游计划篇 制定旅行计划时&#xff0c;尤其是跨国旅游&#xff0c;会涉及到很多独特的英语词汇。以下是与“旅游计划”相关的托业词汇&#xff0c;帮助你更加自如地规划行程。 1. 旅行服务和优惠 出发前了解一下与服务和优惠相关的常用词汇&#…

PVE定时开启关闭虚拟机,实现PVE中群晖虚拟机的定时开机和关闭

如果在PVE中安装了群晖&#xff0c;又不想每天关闭PVE(不在家&#xff0c;怕服务器起不来)&#xff0c;因此想每天定时关闭开启黑群晖和其他虚拟机释放资源。 在网上查了很多&#xff0c;说在crontab添加命令 00 2 * * * pvesh create /nodes/pve/qemu/102/status/stop 00 6 …

JDBC/ODBC—数据库连接API概述

JDBC/ODBC概述 在数据库连接领域&#xff0c;有两种广泛使用的技术&#xff1a;ODBC&#xff08;Open Database Connectivity - 开放数据库连接&#xff09;和 JDBC&#xff08;Java Database Connectivity - Java 数据库连接&#xff09;。 一、什么是 ODBC&#xff1f; Ope…

2024年NSSCTF秋季招新赛-WEB

The Beginning F12看源码&#xff0c;有flag http标头 黑吗喽 题目说要在发售时的0点0分&#xff0c;所以添加标头data Date: Tue, 20 Aug 2024 00:00:00 GMT然后改浏览器头 User-Agent: BlackMonkey曲奇就是Cookie cookieBlackMonkey这个一般就是Referer Referer:wukon…

后台管理系统的通用权限解决方案(十一)SpringBoot的统一异常处理

文章目录 1 统一异常处理介绍2 统一异常处理案例 1 统一异常处理介绍 在实际项目中&#xff0c;不可避免需要处理各种异常。如果每个都单独处理&#xff0c;代码中则会出现大量的try {...} catch {...} finally {...}代码块&#xff0c;不仅有大量的冗余代码&#xff0c;而且还…

Axure使用动态面板制作新闻栏目高级交互

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;使用动态面板制作新闻栏目 主要内容&#xff1a;动态面板State切换、控制&#xff1b;动态面板滚动设置&#xff1b;设置选中 应用场景&#xff1a…

android数组控件Textview

说明&#xff1a;android循环控件&#xff0c;注册和显示内容 效果图&#xff1a; step1: E:\projectgood\resget\demozz\IosDialogDemo-main\app\src\main\java\com\example\iosdialogdemo\TimerActivity.java package com.example.iosdialogdemo;import android.os.Bundl…

2024年10月文章一览

2024年10月编程人总共更新了21篇文章&#xff1a; 1.2024年9月文章一览 2.《Programming from the Ground Up》阅读笔记&#xff1a;p147-p180 3.《Programming from the Ground Up》阅读笔记&#xff1a;p181-p216 4.《Programming from the Ground Up》阅读笔记&#xff…

List 列表基础用法

List 列表基础用法 列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同&#xff0c;它支持数字&#xff0c;字符串甚至可以包含列表&#xff08;所谓嵌套&#xff09;。 列表是写在方括号 [] 之间、用逗号分隔开的元素列表。 和字符串一样&#xff0c;列表…

企业如何通过架构蓝图实现数字化转型

数字化转型的关键——架构蓝图的力量 在当今的商业世界&#xff0c;数字化转型已经不再是一个选择&#xff0c;而是企业生存与发展不可回避的战略行动。企业希望通过数字化提高效率、增强灵活性&#xff0c;并为客户提供更好的体验。然而&#xff0c;数字化转型不仅仅涉及技术…

数字马力二面面试总结

24.03.07数字马力二面面试总结 前段时间找工作,做的一些面试笔记总结 大家有面试录音或者记录的也可以发给我,我来整理答案呀 数字马力二面面试总结 24.03.07数字马力二面面试总结你可以挑一个你的最有挑战性的,有难度的,最具有复杂性的项目,可以简单说一下。有没有和算…

了解SQLExpress数据库

SQLExpress&#xff08;Microsoft SQL Server Express&#xff09;是由微软公司开发的一款免费且轻量级的数据库管理系统。以下是关于SQLExpress的详细解释&#xff1a; 一、定义与特点 定义&#xff1a; SQLExpress是Microsoft SQL Server的一个缩减版或基础版&#xff0c;旨在…

华为荣耀曲面屏手机下面空白部分设置颜色的方法

荣耀部分机型下面有一块空白区域&#xff0c;如下图红框部分 设置这部分的颜色需要在themes.xml里面设置navigationBarColor属性 <item name"android:navigationBarColor">android:color/white</item>

服务器数据恢复—SAN环境中LUN映射错误导致文件系统一致性出错的数据恢复案例

服务器数据恢复环境&#xff1a; SAN光纤网络环境&#xff0c;存储由一组6块硬盘组建的RAID6阵列构成&#xff0c;划分为若干LUN&#xff0c;MAP到跑不同业务的SUN SOLARIS操作系统服务器上。 服务器故障&分析&#xff1a; 因为业务需要&#xff0c;用户在该光纤存储环境中…

【python】OpenCV—Connected Components

文章目录 1、任务描述2、代码实现3、完整代码4、结果展示5、涉及到的库函数6、参考 1、任务描述 基于 python opencv 的连通分量标记和分析函数&#xff0c;分割车牌中的数字、号码、分隔符 cv2.connectedComponentscv2.connectedComponentsWithStatscv2.connectedComponents…

【LangChain系列4】【Chain模块详解】

目录 前言一、LangChain1-1、介绍1-2、LangChain抽象出来的核心模块1-3、特点1-4、langchain解决的一些行业痛点1-5、安装 二、Chain模块2-1、介绍2-2、LLMChain2-3、Sequential Chain&#xff08;顺序链&#xff09;2-4、Router Chain 总结 前言 LangChain给自身的定位是&…

[pdf,epub]105页《分析模式》漫谈合集01

105页的《分析模式》漫谈合集第1集的pdf、epub文件&#xff0c;已上传到本账号的CSDN资源。 如果无法下载&#xff0c;也可以访问umlchina.com/url/ap.html 已排版成适合手机阅读&#xff0c;pdf的排版更好一些。 ★UMLChina为什么叒要翻译《分析模式》&#xff1f; ★[缝合故…

Python酷库之旅-第三方库Pandas(186)

目录 一、用法精讲 861、pandas.Index.names属性 861-1、语法 861-2、参数 861-3、功能 861-4、返回值 861-5、说明 861-6、用法 861-6-1、数据准备 861-6-2、代码示例 861-6-3、结果输出 862、pandas.Index.nbytes属性 862-1、语法 862-2、参数 862-3、功能 8…