类和对象

复制构造函数

只有一个参数,即对同类对象的引用
形如

X::X(X&)
X::X(const X &)//能以常量对象作为参数,二者选一

如果没有定义,编译默认生成。默认的复制构造函数完成复制功能。

class Complex{
    private:
        double real,iamg;
}
Complex c1;//调用缺省无参构造函数
Complex c2(c1);//调用缺省的复制构造函数,将c2初始化和c1一样

起作用的三种情况
1)当用一个对象去初始化同类的两一个对象时
2)若果某函数有一个参数是类A的对象,那么该函数被调用时,类A的复制构造函数将被调用

#include <iostream>

using namespace std;
class A
{
public:
    A(){};
    A(A &a){
        cout<<"Copy constructor called"<<endl;
    }
};
void Func(A a1)
{

}
int main()
{
    A a2;
    Func(a2);
    return 0;
}

输出结果

Copy constructor called//形参a1的值并不等于实参a2

3)若果函数的返回值是类A的对象,则函数返回时,A的复制构造函数被调用
为什么要自己写复制构造函数

类型转换构造函数

实现类型的自动转换
只有一个参数,不是复制构造函数
编译系统会自动调用,调用的时候,会建立一个临时对象/临时变量

析构函数(Destructor)

成员函数的一种
名字与类名相同
在前面加”~”
没有参数和返回值
一个雷最多只有一个析构函数
在对象消亡时,自动被调用,在对象消亡前做善后工作,如释放分配的内存空间等
定义类的时候没写析构函数,则编译器生成缺省析构函数。
调用说明
1)对象数组生命期结束时,对象数组的每个元素的析构函数都会被调用

#include <iostream>

using namespace std;
class Ctest
{
public:
    ~Ctest()
    {
        cout<<"destructor called"<<endl;

    };
};
int main()
{
    Ctest a[2];
    cout<<"end main"<<endl;
    return 0;
}

输出

end main
destructor called
destructor called

2)delete运算导致析构函数被调用

int main()
{
    Ctest *pTest;
    pTest= new Ctest[3];
    delete[] pTest;
}

输出

destructor called
destructor called
destructor called//数组里包含三个对象,析构函数被调用三次

先构造的,后析构
后构造的,先析构

静态成员变量和静态成员函数

静态成员:加入static关键字
普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享
sizeof 运算不会计算静态成员变量
普通成员函数必须作用于某个对象,静态成员函数并不具体作用于某个对象,因此静态成员不需要通过对象就能访问。
静态成员变量本质上是全局变量,哪怕一个对象都不存在,静态成员变量也存在。
静态成员访问方式
1)类名::成员名
2)对象名.成员名
3)指针->成员名
4)引用.成员名
在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数。

this指针

指向成员函数作用的对象

class A
{
    int i;
public: 
    void hello(){cout<<"hello"<<endl;}
};
int main()
{
    A *p=NULL;
    P->Hello();
}

看上去是有问题的,p为空指针,并没有指向实际的A对象,那么p如何调用Hello?实际上

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

编译时,会等价于

void hello(A *this){cout<<"hello"<<endl;}

p->Hello 翻译为 Hello(p);//p作为参数,输出Hello
再看下边一段代码

class A
{
    int i;
public: 
    void hello(){cout<<i<<"hello"<<endl;}
};
int main()
{
    A *p=NULL;
    P->Hello();
}
void hello(){cout<<i<<"hello"<<endl;}
等价为void hello(A *this){cout<<this->i<<"hello"<<endl;}

此时,this为空指针,调用Hello(p)会出错
总结
静态成员函数不作用于任何对象,故不能使用this指针。静态成员函数的真实参数的个数,就是程序中写出的参数个数。

常引用

引用前加const关键字,成为常引用,不能通过常引用,修改其引用的变量
作用
当对象作为函数的参数的时候,生成该参数需要调用复制构造函数,效率比较低。用指针作为参数,会影响代码的美观。此时,可以将对象的引用作为参数。

class Sample{…};
void PrintfObj(Sample &o){…};

对象作为函数的参数也有一定的风险性,若函数中不小心修改了形参o,则实参也跟着变,为了避免这种现象:采用对象的常引用作为参数

void PrintfObj(const Sample &o){…};

这样,函数中就能确保不会出现无意更改o值的语句了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值