0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C/C++之面向对象编程思想2

jf_78858299 来源:小余的自习室 作者:小余的自习室 2023-03-30 15:14 次阅读

C++中的几种特殊成员函数

构造函数

C++在编译器会给我们默认创建一个缺省的构造方法: 如下代码:

class Father {
public:
    string name = "father";
    int age = 45;
    void print() {
        cout << "name:" << name << " age:" << age << endl;
    }
};
class Son :public Father {
public:
    string sex = "male";
};

void extendsTest::mainTest()
{
    Son son;
    son.print();
};
运行结果:name:father age:45

可以看到虽然我们没有明确声明构造方法,但是依然可以调用无参构造方法。这就是因为 编译器自动给我们创建了一个无参构造方法

如果类定义了自己的构造方法后(包括无参和有残),编译器就不会给我们创建了 ,看下面代码:

class Father {
public:
    Father() {
        cout << "Father:" << name << endl;
    }
    string name = "father";
    int age = 45;
    void print() {
        cout << "name:" << name << " age:" << age << endl;
    }
};
class Son :public Father {
public:
    Son(){
        cout << "Son:" << name << endl;
    }
    string sex = "male";    
};

void extendsTest::mainTest()
{
    Son son;
    son.print();
};
打印结果:
Father:father
Son:father
name:father age:45

从上面代码也可以看出C++编译器会默认优先调用父类的构造方法,再调用子类的构造方法,

这点和java中是有区别的,java会从子类开始依次调用父类的构造方法,然后回溯子类的构造方法

所以为了保证对象的顺利创建,需要保证父类的构造方法是有效的。 如下代码:

class Father {
public:
    Father(string _name):name(_name){
        cout << "Father:" << name << endl;
    }
    string name = "father";
    int age = 45;
};

此时父类中创建了一个有参构造方法,前面说过,此时编译器不会创建默认的无参构造方法,则需要保证在其子类中有初始化父类的操作:即调用父类有参构造方法。 如下代码:

class Son :public Father {
public:
    Son(string name):Father(name) {
        cout << "Son:" << name << endl;
    }
    string sex = "male";
};

void extendsTest::mainTest()
{
    Son son1("myName");
};
结果:
Father:myName
Son:myName

析构函数

析构函数用来释放当前对象使用到的内存空间,当对象跳出其作用域范围后就会执行析构函数( 除非是有智能指针出现循环引用的情况,无法释放,导致泄露 )。 C++中析构函数和构造函数相反,会 优先调用子类的析构函数再调用父类的析构函数 。 如下代码:

class Father {
public:
    ~Father() {
        cout << "~Father"<< endl;
    }
    string name = "father";
    int age = 45;

};
class Son :public Father {
public:
    ~Son() {
        cout << "~Son" << endl;
    }   
    string sex = "male";    
};

void extendsTest::mainTest()
{
    Son son;
};
运行结果:
~Son
~Father

拷贝构造

C++中拷贝构造函数格式:

  • 格式1 :带const参数 Complex(const Complex& c) { … } 表示以常量对象作为参数
  • 格式2 :不带const参数 Complex(Complex& c) { … } 表示以非常量作为参数进行拷贝 如下代码:
class Complex {
  public:
    double real, imag;
    Complex(double _real, double _imag):
        real(_real),imag(_imag)
    {
        cout << "real:" << real << " imag:" << imag << endl;
    }
    void print() {
        cout << "real:" << real << " imag:" << imag << endl;
    }
    Complex(Complex& c) {
        real = c.real+1; imag = c.imag+1;
    }
  };

void extendsTest::mainTest()
{
    Complex c1(1.0, 2.0);
    Complex c2(c1);
    c2.print();
};
打印结果:
real:1 imag:2
real:2 imag:3

拷贝构造函数和构造方法类似, C++编译器会给我们提供默认的拷贝构造函数 。 将上面代码的拷贝构造函数删除后:

class Complex {
public:
    double real, imag;
    Complex(double _real, double _imag):
        real(_real),imag(_imag)
    {
        cout << "real:" << real << " imag:" << imag << endl;
    }
    void print() {
        cout << "real:" << real << " imag:" << imag << endl;
    }
};

void extendsTest::mainTest()
{
    Complex c1(1.0, 2.0);
    Complex c2(c1);
    c2.print();
};

依然可以执行拷贝构造,此时c2使用了默认拷贝构造函数进行赋值。

拷贝构造的几种调用形式:

  • 1.当用一个对象去初始化同类的另一个对象时

    Complex c2(c1);
    Complex c2 = c1;
    

    这两天语句是等价的。但是要 注意此时Complex c2 = c1是一个初始化语句,并非一个赋值语句。赋值语句是一个已经初始化后的变量 。 如下:

    Complex c1, c2; c1 = c2 ;
    c1=c2;
    

    赋值语句不会触发拷贝构造

  • 2.当对象作为一个函数形参时,此时也会触发对象的拷贝构造

    class Complex {
      public:
        double real, imag;
        Complex(double _real, double _imag):
            real(_real),imag(_imag)
        {
            cout << "real:" << real << " imag:" << imag << endl;
        }
        Complex(Complex& c) {
            real = c.real+1; imag = c.imag+1;
            cout << "complex copy" << endl;
        }
      };
    
    void func(Complex c) {
        cout << "real:" << c.real << " imag:" << c.imag << endl;
    
    }
    
    void extendsTest::mainTest()
    {   
        Complex c(1.0,2.0);
        func(c);
    };
    
    运行结果:
    real:1 imag:2
    complex copy
    real:2 imag:3
    

    可以看到运行结果触发了Complex的拷贝构造 以对象作为函数的形参,在函数被调用时,生成的形参要用复制构造函数初始化,这会带来时间上的开销。 如果用对象的引用而不是对象作为形参,就没有这个问题了

    void func(Complex& c) {
        cout << "real:" << c.real << " imag:" << c.imag << endl;
    }
    

    但是以引用作为形参有一定的风险,因为这种情况下如果形参的值发生改变,实参的值也会跟着改变。 最好的方法就是将函数形参声明为const类型的引用

    void func(const Complex& c) {
        cout << "real:" << c.real << " imag:" << c.imag << endl;
    }
    
  • 3.对象作为函数返回值返回时,也会触发拷贝构造。

    Complex func() {
        Complex c(1.0, 2.0);
        return c;
      }
      void extendsTest::mainTest()
      { 
        cout << func().real << endl;
      };
    
    结果:
    real:1 imag:2
    complex copy
    2
    

    可以看到此时func函数中的return c处会触发一次拷贝构造,并将拷贝后的对象返回。 这点通过函数hack过程也可以看出来:此处call方法执行的是拷贝构造方法

    图片

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2973

    浏览量

    104886
  • C++
    C++
    +关注

    关注

    22

    文章

    2112

    浏览量

    73737
  • 面向对象编程

    关注

    0

    文章

    22

    浏览量

    1832
收藏 人收藏

    评论

    相关推荐

    Labview 之面向对象编程。 里面有个例子 和视频教程地址

    Labview 之面向对象编程。 里面有个例子 和视频教程地址Labview 之面向对象编程
    发表于 12-29 10:16

    C++ 面向对象多线程编程下载

    C++ 面向对象多线程编程下载
    发表于 04-08 02:14 70次下载

    C++面向对象多线程编程 (pdf电子版)

    C++面向对象多线程编程共分13章,全面讲解构建多线程架构与增量多线程编程技术。第1章介绍了
    发表于 09-25 09:39 0次下载

    C++课件

     C++面向对象程序设计 面向对象思想的由来面向
    发表于 04-10 13:41 0次下载

    Visual C++面向对象与可视化程序设计习题解析与编程

    Visual C++面向对象与可视化程序设计习题解析与编程实例从最基本的概念出发,详细地讲述了使用Visual C++进行
    发表于 07-12 15:16 0次下载
    Visual <b class='flag-5'>C++</b><b class='flag-5'>面向</b><b class='flag-5'>对象</b>与可视化程序设计习题解析与<b class='flag-5'>编程</b>实

    C++编程思想

    C++编程思想,很好的资料,大家下载看看吧!够20字了吧,哈哈哈!
    发表于 11-17 11:38 0次下载

    面向对象的程序设计(C++

    面向对象的程序设计(C++).面向对象的基本思想 C++
    发表于 03-22 14:40 0次下载

    C#入门教程之面向对象编程简介的详细资料概述

    本文档的主要内容详细介绍的是C#入门教程之面向对象编程简介的详细资料概述主要学习的目标是1.面向对象
    发表于 12-05 11:54 35次下载
    <b class='flag-5'>C</b>#入门教程<b class='flag-5'>之面向</b><b class='flag-5'>对象</b><b class='flag-5'>编程</b>简介的详细资料概述

    C++语言和面向对象程序设计教程

    章至第11章介绍符合C++国际标准的C++面向对象程序设计思想和方法;第12章和第13章分别介绍面向
    发表于 03-02 08:00 6次下载

    STM32 C++编程系列二:STM32 C++代码封装初探

    一、STM32与面向对象编程上一章中提到了,C++的核心之一就在于面向对象
    发表于 12-08 11:06 13次下载
    STM32 <b class='flag-5'>C++</b><b class='flag-5'>编程</b>系列二:STM32 <b class='flag-5'>C++</b>代码封装初探

    嵌入式C语言面向对象编程应用及优势

    既然面向对象是一种编程思想,而编程语言只是一种工具,那么,思想与工具之间就不存在一种强耦合的关系
    发表于 11-10 12:00 1808次阅读
    嵌入式<b class='flag-5'>C</b>语言<b class='flag-5'>面向</b><b class='flag-5'>对象</b><b class='flag-5'>编程</b>应用及优势

    C语言是怎么面向对象编程

    在嵌入式开发中,C/C++语言是使用最普及的,在C++11版本之前,它们的语法是比较相似的,只不过C++提供了面向
    的头像 发表于 02-14 13:57 1697次阅读
    <b class='flag-5'>C</b>语言是怎么<b class='flag-5'>面向</b><b class='flag-5'>对象</b><b class='flag-5'>编程</b>

    C/C++之面向对象编程思想1

    C++作为一门在C和Java之间的语言,其既可以使用C语言中的高效指针,又继承了Java中的面向对象编程
    的头像 发表于 03-30 15:14 665次阅读
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>之面向</b><b class='flag-5'>对象</b><b class='flag-5'>编程</b><b class='flag-5'>思想</b>1

    C/C++之面向对象编程思想3

    C++作为一门在C和Java之间的语言,其既可以使用C语言中的高效指针,又继承了Java中的面向对象编程
    的头像 发表于 03-30 15:16 580次阅读
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>之面向</b><b class='flag-5'>对象</b><b class='flag-5'>编程</b><b class='flag-5'>思想</b>3

    浅谈C语言面向对象编程思想

    C语言是一种面向过程的语言,但是也可以用结构体和函数指针来模拟面向对象的特性,比如封装、继承和多态。
    发表于 11-02 12:27 1150次阅读