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

原文地址:https://www.cnblogs.com/shijingjing07/p/5546014.html