iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++构造函数的一些注意事项总结
  • 848
分享到

C++构造函数的一些注意事项总结

2024-04-02 19:04:59 848人浏览 八月长安
摘要

目录1、匿名对象2、拷贝构造函数的调用时机3、深拷贝和浅拷贝总结1、匿名对象 首先应该明确匿名对象,匿名对象是之没有对象名,调用完构造函数后即析构的对象。下面通过代码捕捉类的构造函数

1、匿名对象

首先应该明确匿名对象,匿名对象是之没有对象名,调用完构造函数后即析构的对象。下面通过代码捕捉类的构造函数和析构函数,以进行说明:


#include <iOStream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), m_num2(b) {
        cout << "有参构造函数的调用" << endl;
    };
    Solution(const Solution& s):m_num1(s.m_num1), m_num2(s.m_num2){
        cout << "拷贝构造函数的调用" << endl;
    } 
    ~Solution(){
        cout << "析构函数的调用" << endl;
    }
private:
    int m_num1;
    int m_num2;
};

int main()
{
    Solution(8,9); // Solution(8,9) 匿名对象
    
    system("pause");
    return 0;
}

代码运行结果为:

通过代码运行结果可以看到,创建匿名对象的时候,调用了类的构造函数,随后立即调用了析构函数。我们可以直接利用匿名对象进行初始化类的成员的初始化,代码如下:


#include <iostream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), m_num2(b) {
        cout << "有参构造函数的调用" << endl;
    };
    Solution(const Solution& s):m_num1(s.m_num1), m_num2(s.m_num2){
        cout << "拷贝构造函数的调用" << endl;
    } 
    ~Solution(){
        cout << "析构函数的调用" << endl;
    }

    int m_num1;
    int m_num2;
};

int main()
{
    Solution s1(Solution(8,9));
    // Solution s1 = Solution(8,9); //显式 Solution(8,9) 匿名对象初始化类成员
    // Solution s1 = {8,9};        //{8,9}等价于Solution(8,9)
    cout << "s1.m_num1 = " << s1.m_num1 << endl;
    cout << "s1.m_num2 = " << s1.m_num2 << endl;   
    system("pause");
    return 0;
}

运行结果如下:

代码调用了一次构造函数,可见匿名对象可以初始化类成员,就是将匿名对象转化成了s1对象,这里需要与拷贝构造函数区分开:


#include <iostream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), m_num2(b) {
        cout << "有参构造函数的调用" << endl;
    };
    Solution(const Solution& s):m_num1(s.m_num1), m_num2(s.m_num2){
        cout << "拷贝构造函数的调用" << endl;
    } 
    ~Solution(){
        cout << "析构函数的调用" << endl;
    }

    int m_num1;
    int m_num2;
};

int main()
{
    Solution s1(10,11);
    Solution s2(s1);
    cout << "s2.m_num1 = " << s2.m_num1 << endl;
    cout << "s2.m_num2 = " << s2.m_num2 << endl;
    system("pause");
    return 0;
}

代码运行结果为:

对比以上两个代码可以发现,通过匿名对象初始化类成员并不是拷贝构造,只是一种替换,通过匿名对象初始化类成员并不会调用拷贝构造函数。

2、拷贝构造函数的调用时机

今年秋招笔试题最爱考查构造函数的调用时机,通常会结合继承和多态来考察,这里先说明一下拷贝构造函数的调用时机,后面再详细说明带继承和多态的构造函数调用时机。

一、使用一个已经创建的对象来初始化一个新对象,如上面的代码,创建对象s1的时候调用了有参构造函数,通过s1来初始化s2的时候调用了拷贝构造。

二、函数的参数是需要值传递的对象的时候

三、函数返回对象的时候

下面通过代码验证,当函数的参数是一个需要值传递的对象的情况:


#include <iostream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), m_num2(b) {
        cout << "有参构造函数的调用" << endl;
    };
    Solution(const Solution& s):m_num1(s.m_num1), m_num2(s.m_num2){
        cout << "拷贝构造函数的调用" << endl;
    } 
    ~Solution(){
        cout << "析构函数的调用" << endl;
    }
public:
    int m_num1;
    int m_num2;
};

void showClassNum(Solution s) {
    cout << s.m_num1 << endl;
    cout << s.m_num2 << endl;
}

int main()
{
    Solution s1(10,11);
    showClassNum(s1);
    system("pause");
    return 0;
}

代码运行结果为:

通过代码运行结果可以看到,s1对象调用了有参构造函数,当把s1传给函数的参数s的时候调用了拷贝构造函数,函数执行完调用了s对象的析构函数。

当函数的返回值是一个对象的时候,也会调用拷贝构造函数:


#include <iostream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), m_num2(b) {
        cout << "有参构造函数的调用" << endl;
    };
    Solution(const Solution& s):m_num1(s.m_num1), m_num2(s.m_num2){
        cout << "拷贝构造函数的调用" << endl;
    } 
    ~Solution(){
        cout << "析构函数的调用" << endl;
    }

    void changeNum(int a, int b) {
        m_num1 = a;
        m_num2 = b;
    }

    void showNum() {
        cout << "m_num1 = " << m_num1 << endl;
        cout << "m_num2 = " << m_num2 << endl;
    }
public:
    int m_num1;
    int m_num2;
};

Solution clearClassNum(Solution s) {
    s.changeNum(0,0);
    return s;
}

int main()
{
    Solution s1 (10,10);
    s1 = clearClassNum (s1);
    s1.showNum();
    system("pause");
    return 0;
}

代码运行结果为:

从代码运行结果可以看出来,函数传参的时候调用了拷贝构造,然后函数返回一个对象的时候的也调用了拷贝构造。

需要注意的是,函数要返回对象的时候,不要使用引用的方式返回,因为函数的内的变量存放在堆栈区,在函数执行完毕后就会释放这块内存,引用就会出现问题。

3、深拷贝和浅拷贝

面试的时候比较喜欢问的问题,首先浅拷贝就是我们常用的拷贝,实现了对象成员的拷贝,深拷贝就是在堆区申请空间,然后再进行拷贝操作,浅拷贝可以由编译器完成,但是深拷贝需要我们自己完成,就是有在堆区开辟的内存,就一定要自己提供拷贝构造函数,防止浅拷贝带来的重复内存释放问题。代码验证如下:


#include <iostream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), pm_num2(new int(b)) {
        cout << "有参构造函数的调用" << endl;
    };
      //如果不利用深拷贝在堆区创建新内存,会导致浅拷贝带来的重复释放堆区问题,导致程序出错
    Solution(const Solution& s):m_num1(s.m_num1), pm_num2(new int(*s.pm_num2)) {
        cout << "拷贝构造函数的调用" << endl;
    }
    ~Solution(){
        cout << "析构函数的调用,释放堆区申请的内存" << endl;
        if (pm_num2 != nullptr) {
            delete pm_num2;
        }
    }

    void changeNum(int a, int b) {
        m_num1 = a;
        *pm_num2 = b;
    }

    void showNum() {
        cout << "m_num1 = " << m_num1 << endl;
        cout << "m_num2 = " << *pm_num2 << endl;
    }
public:
    int m_num1;
    int* pm_num2;
};

void func()
{
    Solution s1 (10,10);
    Solution s2(s1);
    s2.showNum();
}

int main()
{

    func();
    system("pause");
    return 0;
}

代码运行结果为:

总结

到此这篇关于c++构造函数注意事项的文章就介绍到这了,更多相关C++构造函数注意事项内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++构造函数的一些注意事项总结

本文链接: https://www.lsjlt.com/news/156075.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++构造函数的一些注意事项总结
    目录1、匿名对象2、拷贝构造函数的调用时机3、深拷贝和浅拷贝总结1、匿名对象 首先应该明确匿名对象,匿名对象是之没有对象名,调用完构造函数后即析构的对象。下面通过代码捕捉类的构造函数...
    99+
    2024-04-02
  • python编写函数注意事项总结
    1、编写注意 (1)给函数指定描述名。 (2)函数名称只包括小写字母和下划线。 (3)每一个函数都应该包含简要说明其功能的注释,注释应该紧跟在函数定义之后,并且采用文档字符串格式。 ...
    99+
    2024-04-02
  • C++中vector容器的注意事项总结
    目录容量(capacity)和大小(size)的区别容器扩容的本质emplace_back()和push_back()的区别emplace()和insert()的区别附:如果vect...
    99+
    2024-04-02
  • C++虚函数注意事项
    目录一、虚函数注意事项1.构造函数2.析构函数3.友元4.没有重新定义5.重新定义将隐藏方法文章转自公众号:Coder梁(ID:Coder_LT) 一、虚函数注意事项 在之前的文章当...
    99+
    2024-04-02
  • C++ 函数继承详解:在继承中使用构造函数和析构函数时应注意哪些事项?
    在 c++++ 继承中,构造函数继承要求派生类构造函数第一个语句调用基类构造函数,析构函数继承要求派生类析构函数先执行派生类代码再调用基类析构函数。注意避免循环调用构造函数和析构函数,确...
    99+
    2024-05-04
    继承 c++函数 c++
  • C++中拷贝构造函数的总结详解
    1.什么是拷贝构造函数: 拷贝构造函数嘛,当然就是拷贝和构造了。(其实很多名字,只要静下心来想一想,就真的是顾名思义呀)拷贝又称复制,因此拷贝构造函数又称复制构造函数。百度百科上是这...
    99+
    2022-11-15
    拷贝构造函数 C++
  • Golang函数的使用注意事项和最佳实践总结
    Golang是一门非常流行的编程语言,不仅因为它的效率和性能优秀,还因为它非常容易学习和使用。在Golang中函数是一个非常重要的概念,函数不仅可以帮助我们组织代码,还可以简化代码逻辑。但是,使用函数也需要遵循一定的注意事项和最佳实践,本文...
    99+
    2023-05-16
    最佳实践 Golang函数 使用注意事项
  • oracle 11g的安装注意事项总结
    oracle 11g 安装注意事项 1、首先时这个配置安全更新页面,不需要填写电子邮件,下面安全更新也取消候选,否则一旦出现软件更新,会拖慢我们的使用进度 2、在安装选项这里,就选...
    99+
    2024-04-02
  • Python requests库参数提交的注意事项总结
    字典与json字符串区别 # python 中的字典格式,是dict类型 {'a': 'sd'} 如果声明a = {"a": "sd"},它仍是字典,不过python会默认将双引...
    99+
    2024-04-02
  • plsql导出表结构要注意哪些事项
    在导出 PL/SQL 表结构时,需要注意以下事项: 确保有足够的权限:在导出表结构之前,确保你有足够的权限来访问和导出表的结构。...
    99+
    2024-04-09
    plsql
  • C++ 函数预处理器的注意事项有哪些?
    注意事项:区分宏定义和函数声明,使用 #define 和 extern 分别定义。谨慎使用宏扩展,避免意外结果。使用逗号分隔宏定义中的参数。避免嵌套宏的使用。通过 #if 等条件表达式创...
    99+
    2024-04-11
    c++ 预处理
  • C++构造函数一些常见的坑
    文章转自微信 公众号:Coder梁(ID:Coder_LT) 某一天我们接到了一个需求,需要开发一个类似于STL中string的类。 我们很快写好了代码: #include <...
    99+
    2024-04-02
  • 使用Java构造器时需要注意哪些事项
    今天就跟大家聊聊有关使用Java构造器时需要注意哪些事项,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java构造器使用方法及注意事项超类的构造器在子类的构造器运行之前运行,也就是说...
    99+
    2023-05-31
    java ava
  • C++ 函数中默认参数的注意事项
    c++++ 函数中默认参数需要注意:必须出现在参数列表末尾。不可为同一参数指定多个默认值。vararg 可变数量参数不可拥有默认值。默认参数不可被重载函数的参数共享。 C++ 函数中默...
    99+
    2024-04-20
    函数 c++ 默认参数
  • C++ 函数重载的限制和注意事项有哪些?
    函数重载的限制包括:参数类型和顺序必须不同(相同参数个数时),不能使用默认参数区分重载。此外,模板函数和非模板函数不能重载,不同模板规范的模板函数可以重载。值得注意的是,过度使用函数重载...
    99+
    2024-04-13
    c++ 函数重载 限制 编译错误
  • 使用 C++ 内联函数需要注意哪些事项?
    c++++内联函数在编译时直接展开,避免函数调用开销。事项包括:1. 函数体小(建议10行以内);2. 避免循环和递归;3. 注意内联展开仅在同文件范围内。实战案例中,计算三角形面积的内...
    99+
    2024-04-16
    编程 c++内联函数 c++
  • 关于BindingResult的使用总结及注意事项
    目录BindingResult总结及注意事项相关的校验API空检查长度检查Booelan检查日期检查其他验证数值检查项目使用中遇到的问题BindingResult作用原理Bindin...
    99+
    2024-04-02
  • python切片中内存的注意事项总结
    1、由于 Python 列表的切片会在内存中创建新对象,因此需要注意的另一个重要函数是itertools.islice。 2、通常需要遍历切片,而不仅仅是在内存中静态创建它。isli...
    99+
    2024-04-02
  • C++ 函数重写的注意事项和陷阱
    函数重写时必须遵循以下注意事项:函数签名相同访问修饰符不能比基类的更严格使用 const 或 override 标记重写只有虚函数才能被重写陷阱包括隐藏基类函数、多重重写和无意重写。正确...
    99+
    2024-04-19
    c++ 函数重写
  • C/C++开发中extern的一些使用注意事项
    目录前言数组与指针的区别具体分析extern "C"前言 前些日子,有友友问了我这样的一道问题: 数组通过外部声明为指针时,数组和指针是不能互换使用的;那么请思...
    99+
    2023-01-04
    C/C++开发extern使用事项 C C++ extern
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作