• C++类的构造函数详解


    1.默认构造函数
    1) 当没有定义任何构造函数时,编译器会提供默认构造函数,可以直接使用。
    2) 如果定义了带参数的构造函数,又需要使用默认构造函数,此时,必须显式定义无参构造函数,这和C#中有很大的不同。例如有一个蔬菜类Veg:
    Veg(const char* name,int num,double price);//声明了带三个参数的构造函数
    要初始化Veg对象,可使用
    Veg veg("tomato",15,3.5);

    3) 定义了带参数的构造函数的同时,又需要使用Veg veg;若带参数的构造函数,参数全部用默认值,如:

    Veg(const char* name="NONE",int num=0,double price=0.0);
    则可成功初始化对象,否则将报错,
    要使用默认构造函数,必须显式声明
    Veg veg();//声明了默认构造函数

    2.创建并初始化对象的几种方式
    1)Veg veg("tomato",15,3.5);
    在栈中,创建一个名为veg的Veg对象,并调用构造函数初始化
    2)Veg veg=Veg("tomato",15,3.5);
    和方法一原理一样
    3)Veg veg;
    无参构造函数或参数全部有默认值的构造函数的初始化

    以上三种方式创建的对象,是放在栈中的,当作用域结束时,析构函数将被隐式调用,对象将被释放。

    4)Veg *p = new veg("tomato",15,3.5);
    在堆中,创建一个Veg对象,并调用构造函数初始化,并返回指向该对象的指针p
    关于new的详细介绍,可参考 C++ new操作符详解 

    堆中创建的对象,在不需要使用时,要使用delete关键字,删除指针,此时析构函数会立即被隐式调用,指针指向的对象将被释放,
    否则的话,将造成内存泄漏。

    3.对象赋值
    Veg veg1=Veg("tomato",15,3.5);
    Veg veg2 = veg2;
    属于值传递,对象中每个数据成员的值都将复制到目标对象相应的数据成员。

    4.关于只带一个参数的构造函数

    只有一个惨的构造函数初始化时,可以将对象初始化为该参数,语法如下:
    Classname object= value;

    编程时,我们使用了很多此种初始化方式,简洁明了,如:
    int a(10)=>int a = 10;
    string a("hello")=>string a= "hello";

    然而,很多时候,此种初始化方式,是不对的。如:
    针对构造函数Veg(const char* name);我们可以直接初始化为:
    Veg veg = name;
    显然,Veg对象并不是一个char*类型的字符串,那么如何避免误用此种初始化方式呢?
    可在构造函数声明时,加上explicit关键字,如:explicit Veg(const char* name);
    explicit关键字的详细介绍,可参考 C++ explicit关键字 

    5.构造函数使用示例

    如下例所示,定义了一个蔬菜类Veg,main函数中演示了几种构造函数初始化方式。

    Veg.h

    #pragma once
    #include<iostream>
    #include<string>
    class Veg
    {
    private:
        std::string name;
        int num;
        double price;
        double total;
        void set_tot(){total = num*price;}
    public:
        Veg();
        Veg(const std::string &name);
        Veg(const std::string &name,int num=0,double price = 0.0);
        ~Veg();
        void show();
    };

    Veg.cpp

    #include "Veg.h"
    Veg::Veg()
    {
        name="NONE";
        num = 0;
        price = 0.0;
        total = 0.0;
    }
    Veg::Veg(const std::string &name)
    {
        this->name=name;
    }
    Veg::Veg(const std::string &name,int num,double price)
    {
        this->name = name;
        this->num = num;
        this->price  = price;
        set_tot();
    }
    Veg::~Veg()
    {
        std::cout<<"~Veg()"<<std::endl;
    }
    void Veg::show()
    {
        std::cout<<"name:"<<name<<" num:"<<num<<" price:"<<price<<" total:"<<total<<std::endl;
    }

    useveg.cpp

    #include "Veg.h"
    int main()
    {
        Veg veg1;
        Veg veg2("tomato",15,3.5);
        Veg veg3=Veg("potato",8,2.0);
        Veg *p=new Veg("tomato",15,3.5);
        veg1.show();
        veg2.show();
        veg3.show();
        veg2 = veg3;
        veg2.show();
        veg3.show();
        delete p;
        p=NULL;
        return 0;
    }

    运行结果:

    参考资料:《C++ Primer.Plus》 pp.352-363

  • 相关阅读:
    6-Python爬虫-分布式爬虫/Redis
    ES 查询时 排序报错(fielddata is disabled on text fileds by default ... )解决方法
    Intellij Idea webstorm 激活
    Intellij Idea 配置jdk
    java 获取(格式化)日期格式
    js 跳转 XSS漏洞 预防
    CSS去掉背景颜色
    js对象无法当成参数传递 解决方法
    Elasticsearch java api
    java多条件查询SQL语句拼接的小技巧
  • 原文地址:https://www.cnblogs.com/shijingjing07/p/5546014.html
Copyright © 2020-2023  润新知