C++分析——常用技巧(一)

本文探讨了C++中的类构造函数和析构函数,包括初始化、重载及析构的注意事项。接着介绍了复制构造函数的工作原理和使用方法,以及如何通过成员函数调用带参数的构造函数。此外,文章还详细讲解了类的重载机制,如方法重载和运算符重载,并提供了实例代码展示。最后,简述了C++的内联函数及其应用。
摘要由CSDN通过智能技术生成

C++ 类的构造函数和析构函数

类的析构函数可以用来做简单的初始化数据,比如为变量赋值,指针赋NULL,数组和结构体清零等初始化操作。也可以对成员函数进行逗号初始化赋值,构造函数可以进行重载,但析构函数不能。以指针的形式初始化的类在函数结尾要delete指针才能调用到析构函数,而已结构体的形式初始化的类在其作用域结束后自动释放内存,调用析构函数。
测试使用的类

class Module_CPP
{
public:
        Module_CPP():m_module_a(3),m_module_b(5),pm_module(NULL){};
        Module_CPP(int number);
        Module_CPP(int a,int b);
Module_CPP(const Module_CPP & x);
        ~Module_CPP();
        void Init();

private:    
        int m_module_a;
        int m_module_b;
        char *pm_module;
};

构造函数可以使用传统函数的形式进行对成员函数的赋值,也可以收冒号的形式进行快速赋值。

测试代码:

Module_CPP::Module_CPP(int number)
{
        m_module_a = number;
        m_module_b = number * 2;
}

Module_CPP::Module_CPP(int a,int b):m_module_a(a),m_module_b(b),pm_module(NULL)
{

}

Module_CPP::Module_CPP(const Module_CPP & x):m_module_a(x.m_module_b),m_module_b(x.m_module_a)
{
        cout << "copy constructor."<<endl;
}

Module_CPP::~Module_CPP()
{
        m_module_a = 0;
        m_module_b = 0;
        pm_module = NULL;

cout << "APP exit" << endl

}

void Module_CPP::Init()
{
        cout << "m_module_a is " << m_module_a << endl;
        cout << "m_module_b is " << m_module_b << endl;
}

类的初始化与重载

测试方法

    Module_CPP *pModule_1 = new Module_CPP();
    Module_CPP *pModule_2 = new Module_CPP(4);
    Module_CPP Module_1 = Module_CPP(5);

    pModule_1->Init();
    pModule_2->Init();  
    Module_1.Init();

执行结果

$ ./project.o 
m_module_a is 3
m_module_b is 5
m_module_a is 4
m_module_b is 8
m_module_a is 5
m_module_b is 10
APP exit
$

指针的形式申请的类需要在使用结束时释放内存

    Module_CPP *pModule_1 = new Module_CPP();
    Module_CPP *pModule_2 = new Module_CPP(4);
    Module_CPP Module_1 = Module_CPP(5);

    pModule_1->Init();
    pModule_2->Init();  
    Module_1.Init();

    delete pModule_1;
    delete pModule_2;
    pModule_1 = NULL;
    pModule_2 = NULL;

执行结果

$ ./project.o 
m_module_a is 3
m_module_b is 5
m_module_a is 4
m_module_b is 8
m_module_a is 5
m_module_b is 10
APP exit
APP exit
APP exit
$

复制构造函数

复制构造函数是将原先初始化的类成员函数的值赋值给新的函数
复制构造函数写法。

//复制构造函数规则可以自定义,此时的m_module_a和m_module_b的值进行了互换
Module_CPP::Module_CPP(const Module_CPP & x):m_module_a(x.m_module_b),m_module_b(x.m_module_a)
{
        cout << "copy constructor."<<endl;
}

使用方法

    Module_CPP Module_1 = Module_CPP(5);
    Module_CPP Module_2 = Module_1;

    Module_1.Init();
    Module_2.Init();

执行结果

$ ./project.o 
copy constructor.
m_module_a is 5
m_module_b is 10
m_module_a is 10
m_module_b is 5
APP exit
APP exit
$

带参数的成员函数类的构造函数

一个类的成员变量为这个测试类,若初始化未传参的话会默认调用Module_CPP();的构造函数。

class CSystem
{
public:
        CSystem();
CSystem(int a,int b);
        ~CSystem();
        void Init();

private:
        Module_CPP  m_module_cpp;
};

若需要将成员变量的类调用带参的构造函数,则必须在类的构造函数中用冒号的形式赋值。

CSystem::CSystem()
{

}

CSystem::CSystem(int a,int b):m_module_cpp(a,b)
{

}

void CSystem::Init()
{
        m_module_cpp.Init();
}

测试方法:

    CSystem *pSystem_CPP_1 = new CSystem;
    CSystem *pSystem_CPP_2 = new CSystem(12,35);

    pSystem_CPP_1->Init();
    pSystem_CPP_2->Init();

    delete pSystem_CPP_1;
    delete pSystem_CPP_2;
    pSystem_CPP_1 = NULL;
    pSystem_CPP_2 = NULL;

执行结果:

$ ./project.o 
m_module_a is 3
m_module_b is 5
m_module_a is 12
m_module_b is 35
$

C++ 类的重载

类不止是在构造函数重载,最主要的是对方法函数甚至是运算符进行重载。

方法重载

函数方法名相同,但传入的参数类型或数目不同,进而执行不同的功能,这是C++方法的重载。传入的参数类型或数目相同,但返回值不同,不是重载,违反因果关系,无法编译通过。

重载的方法函数

class Module_CPP
{
public:
        Module_CPP();
        ~Module_CPP();

        void Module_Func();
        void Module_Func(int a);
        void Module_Func(char a);
        void Module_Func(int a,int b);
        void Module_Func_Run();
}

重载方法函数:

void Module_CPP::Module_Func()
{
        cout << __func__ << " is called." << endl;
}

void Module_CPP::Module_Func(int a)
{
        cout << __func__ << " is called. a is " << a << endl;
}

void Module_CPP::Module_Func(char a)
{
        cout << __func__ << " is called. a is " << a << endl;
}

void Module_CPP::Module_Func(int a,int b)
{
        cout << __func__ << " is called. a is " << a;
        cout << " b is " << b << endl;
}

运行方法:

    Module_CPP *pModule = new Module_CPP();

    pModule->Module_Func();
    pModule->Module_Func(4);
    pModule->Module_Func('z');
    pModule->Module_Func(5,8);

    delete pModule;
    pModule = NULL;

执行结果:

$ ./project.o 
Module_Func is called.
Module_Func is called. a is 4
Module_Func is called. a is z
Module_Func is called. a is 5 b is 8
APP exit
$

运算符重载

运算符重载后不会改变其优先级关系,几乎所有的运算符都可以重载,只有以下几个运算符不能进行重载:成员运算符“.”、作用域运算符“::”、长度计算运算符“sizeof”、条件运算符“?:”以及强转运算符static_cast、const_cast、reinterpret_cast、dynamic_cast。

运算符重载可以自己定义重载规则,返回值可以是整数,也可以是一个类。

运算符重载调用

示例源码:

class Test_operator
{
public:
    Test_operator():x(0),y(0){}
    Test_operator(int a,int b):x(a),y(b){}
    ~Test_operator(){x = 0;y = 0;}
    int Read_Value_x(){return x;}
    int Read_Value_y(){return y;}
    int operator*(const Test_operator &S)
    {
        return (this->x * S.x) + (this->y * S.y);
    }

    Test_operator operator+(const Test_operator &S)
    {
        Test_operator S1;
        S1.x = this->x + S.x;
        S1.y = this->y + S.y;

        return S1;
    }
    Test_operator &operator<<(const int a)
    {
        this->x += a;
        this->y += a * a;

        return *this;
    }

private:
    int x;
    int y;  
};

测试代码:

    Test_operator Test1(2,5);
    Test_operator Test2(7,9);

    cout << "Test1 * Test2 = " << Test1 * Test2 << endl;

    Test1 << 3;
    Test2 << 5 << 7;
    cout << "Test1 x = " << Test1.Read_Value_x() << " y = " << Test1.Read_Value_y() << endl;
    cout << "Test2 x = " << Test2.Read_Value_x() << " y = " << Test2.Read_Value_y() << endl;

    Test_operator Test3 = Test1 + Test2;
    cout << "Test3 x = " << Test3.Read_Value_x() << " y = " << Test3.Read_Value_y() << endl;

    Test3 = Test1 + Test2 + Test3;
    cout << "Test3 x = " << Test3.Read_Value_x() << " y = " << Test3.Read_Value_y() << endl;

执行结果:

Test1 * Test2 = 59          // 59 = 2*7+5*9
Test1 x = 5 y = 14          // x=5=2+3          y=14=5+3*3
Test2 x = 19 y = 83         // x=19=7+5+7       y=83=9+5*5+7*7
Test3 x = 24 y = 97         // x=24=5+19        y=97=14+83
Test3 x = 48 y = 194        // x=48=5+19+24 y=194=14+83+97

类调用父类运算符

继承基类时,如果父类有运算符重载,子类需要调用父类的运算符操作

继承类

class Coperator : public Test_operator
{
public:
        Coperator(){}
        Coperator(int x,int y):Test_operator(x,y){}
        ~Coperator(){}

        void Module_Value_add(Test_operator &value);
};

void Coperator::Module_Value_add(Test_operator &value)
{
        Test_operator TestValue = operator+(value); //调用继承的运算符重载

        cout << "TestValue x = " << TestValue.Read_Value_x() << " y = " << TestValue.Read_Value_y() << endl;
}

测试代码

Test_operator   Test1(2,5);
    Coperator   TestCoperator(6,7);

    TestCoperator.Module_Value_add(Test1);

执行结果

./project.o 
TestValue x = 8 y = 12

C++ 类的内联函数 inline

类的内联函数代替C语言中的宏定义作用,若代码执行时间很短,则将函数定义为内联函数,节省调用时间。
在函数前面加上内联函数的关键字inline,该函数则为内联函数,在头文件的声明中直接实现方法函数,其本身自动就成为内联函数。

内联函数测试类定义。

class Test_inline
{
public:
    Test_inline(int a,int b):m_a(a),m_b(b){}        
    virtual ~Test_inline()
    {
        m_a = 0;
        m_b = 0;
    }

    int Min()           //直接在声明中定义方法其实就是内联函数,等价于inline int Min()
    {
        return m_a < m_b ? m_a : m_b;
    }   
    inline int Max()        //也可以强制加上内联函数关键字inline
    {
        return m_a > m_b ? m_a : m_b;
    }

private:
    int m_a;
    int m_b;
};

示例代码:

    Test_inline *p = new Test_inline(6,9);
    cout << "Max is " << p->Max() << endl;
    cout << "Min is " << p->Min() << endl;

    delete p;
    p = NULL;   

执行结果:

$ ./project.o 
Max is 9
Min is 6
$
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值