Android NDK篇-C++ 自定义命名空间与拷贝构造函数

本文介绍了C++中的命名空间使用,包括如何定义和全局/局部作用域的调用。接着讲解了构造函数的原理,特别是参数传递中的深拷贝与浅拷贝,并探讨了析构函数的职责。最后,详细阐述了拷贝构造函数的概念,展示了如何自定义拷贝构造函数,并通过实例说明了不同赋值操作下拷贝构造函数的触发情况。
摘要由CSDN通过智能技术生成
1.自定义命名空间
namespace tangsan {
    int age = 20;
    char * level = "唐三是封号斗罗";
void show() {
    cout << "level:" << level << ", age:" << age << endl;
}

 void doAction() {
    cout << "唐三 在嘉陵关大战比比东" << endl;
 }
}

//这样使用是全局属性 全局可用
using namespace tangsan;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //局部可用
    using namespace tangsan;

    show();

    return a.exec();
}

使用命名空间可以直接调用命名空间内部的函数。

2.c++构造函数
class Student {

public:
    Student() {
        cout << "空参数构造函数" << endl;
    }

    // 先调用两个参数的,再调用一个的
    Student(char *name) :Student(name, 87) {
        cout << "一个参数的构造函数" << endl;
        this->name = name;
    }

    // :name(name) 等价 this->name = name;
    /*Student(char * name) :name(name) {
        cout << "一个参数的构造函数" << endl;
    }*/

    // 两个参数的构造函数
    Student(char *name, int age) {
        
        //浅拷贝
        // this->name = name;

        // 堆区深拷贝
        this->name = (char *) (malloc(sizeof(char *) * 10));
        strcpy(this->name, name);

        this->age = age;
        cout << "两个参数的构造函数" << endl;
    }
    
    

    // 析构函数 Student对象的,Student对象被回收了,你做一些释放工作
    // delete stu 的时候,我们的析构函数一定执行
    // free不会执行析构函数,也意味着,你没法在析构函数里面,做释放工作, malloc也不会调用构造函数
    ~Student() {
        cout << "析构函数" << endl;

        // 必须释放 堆区开辟的成员
        if (this->name) {
            free(this->name);
            this->name = nullptr; // 执行NULL的地址,避免出现悬空指针
        }
    }

  • Student(char *name) :Student(name, 87):这样会先执行两个参数的构造方法,然后再执行一个参数的构造方法。
  • this->name = name:表示数值的浅拷贝。
  • this->name = (char *) (malloc(sizeof(char *) * 10)):表示数值的深拷贝,在堆区开辟的空间,需要手动释放。
  • 通过malloc在堆区申请的内存,需要使用free来释放内存,通过new关键字申请的内存,需要使用delete来释放内存。free不会执行析构函数,也意味着,你没法在析构函数里面做释放工作, malloc也不会调用构造函数,所以可以直接使用free来释放。
  • new/delete 是一套 会调用构造函数 与 析构函数
  • malloc/free是一套 不调用构造函数 与 析构函数, C的范畴,不推荐但是也是可以使用。
3.拷贝构造函数
class Douluo{
    // 私有属性
public:
    char *name;
    int level;

public:
    Douluo() { cout << "空参数构造函数" << endl; }

    // 两个参数的构造函数
    Douluo(char *name, int level) : name(name), level(level) {
        cout << "两个参数构造函数" << endl;
    }


    // ~Student(char * name) { } 这样写,就不是析构函数了
    ~Douluo(){
        cout<<"析构函数"<<endl;
    }


    //拷贝构造函数  拷贝构造函数 就是传了一个  自身的常量引用
    Douluo(const Douluo & douluo){   //常量引用:只读的,不让你修改
        cout<<"拷贝构造函数"<<endl;
        this->name=douluo.name;
        this->level=douluo.level-10;
    }

};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //在栈区申请的内存
    Douluo douluo = { "唐三",100};
    //将一个对象赋值给另外一个对象  会触发拷贝构造函数
    Douluo douluo2=douluo;  //会执行拷贝构造函数  需要自己去赋值,否则没数据

//    Douluo douluo2;   //会执行空参数构造函数
//    douluo2=douluo; //这样不会执行拷贝构造函数 但是会默认赋值


    //执行了拷贝构造函数  两个对象的地址不一样

    cout << "main douluo=" << &douluo << endl;
    cout << "main douluo2=" << &douluo2 << endl;
    cout << "main douluo2=" << douluo2.name <<" level="<<douluo2.level<< endl;



      Douluo *douluo3 =new Douluo("小舞",100);
      Douluo *douluo4=douluo3;   //指针指向同一个地址  一个改了,就同时改了,这里压根不会执行拷贝构造函数
      douluo4->level=99;  //“->”调用一级指针的成员

      cout << "main douluo4=" << douluo4->name <<" level="<<douluo4->level<< endl;
      cout << "main douluo3=" << douluo3->name <<" level="<<douluo3->level<< endl;

    return a.exec();
}

  • 自定义拷贝构造函数:只需要在空参构造函数的基础上,传入常量引用就可以了。添加const的意义是为了提升性能,否则传入参数会再拷贝一份,如果添加const就不会再进行拷贝了。

  • Douluo douluo2=douluo:这个操作会触发拷贝构造函数,需要自己去赋值,否则没数据。

  • Douluo douluo2 douluo2=douluo:但是先声明再赋值就不会触发构造函数,会自动赋值。

  • 如果通过new的方式初始化的指针类型,是不会触发拷贝构造函数的。

  • “->”调用一级指针的成员

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值