NDK开发之C++语言学习第三节课内容回顾笔记

一、介绍了C++的命名空间概率.
C++可以用namespace关键字自定义命名空间

//自定义命名空间
namespace lin {
    int age;
    char *name;

    void show() {
         //打印 C++中的打印方式 
        cout << "age = "<<  age << " name = "<<  name << endl;
    }
    void action(){
        //打印 C++中的打印方式 
        cout << " lin action" << endl;
    }
}

然后可以通过using namespace lin; 声明命名空间, 然后可以通过两种方式来使用命名空间内的属性和方法.
第一种

int main() {
    using namespace lin ;
    lin::age = 18;
    lin::name = "林俊杰";
    lin::show();
    lin::action();
    return 0;
}

打印结果如下:


image.png

第二种:

int main() {
    using namespace lin ;
    age = 18;
    name = "林俊杰";
    show();
    action();
    return 0;
}

打印结果如下:


image.png

两个结果是一样的 都可以使用命名空间的属性和函数,但是第二种方面有个缺点就是 如果命名空间里面有重复的函数和属性时,就不能通过第二种方式.
在自定义一个命名空间 lin2,里面在定义一个跟lin一样的属性age和函数action

namespace lin2 {
    int age;
    void action(){
         //打印 C++中的打印方式 
        cout << " Lin2 action" << endl;
    }
}

然后再main方法中声明using namespace lin2,并通过第二种方式使用定义的age和action;


image.png

我们可以看到直接编译不通过,提示我们调用的action方法不明确,因为有两个action 编译器不知道使用的是哪一个. 所以在有重复的属性和函数的时候使用第一种方法,没有的时候使用第二种,毕竟第二种使用方便.

C++的命名空间是可以嵌套的就是可以在命名空间里面在嵌套一个命名空间.

namespace lin3{
    namespace Inner1{
        namespace Inner2{
            namespace Inner3{
                void out(){
                     //打印 C++中的打印方式 
                    cout << "这是命名空间嵌套" << endl;
                }
            }
        }
    }
}

使用的时候 还是先声明 using namespace lin3::Inner1::Inner2::Inner3;

int main() {
    using namespace lin3::Inner1::Inner2::Inner3;
    out(); //第二种方式使用
    lin3::Inner1::Inner2::Inner3::out();  //第一种方式使用
    return 0;
}

打印结果如下:


image.png

二、C++的构造函数, C++里面也是有构造函数的, 结构类型跟java很像
C++中的构造函数也是用关键字class修饰的 ,里面也是有公有属性和私有属性, 空参构造和有参构造

class Student {  //构造函数
public: //公有属性
    //空参构造
    Student() {
        //打印 C++中的打印方式 
        cout << "空参构造函数" << endl;
    }
    //一个参数的构造函数
    Student(char *name) {
        this->name = name;
    //打印 C++中的打印方式 
        cout << "一个参数构造函数 name = " << this->name << endl;
    }
    //两个参数的构造函数
    Student(char *name,int age) {
        this->name = name;
        this->age = age;
        //打印 C++中的打印方式 
        cout << "两个个参数构造函数 name = " << this->name << " age = "<< this->age << endl;
    }
private: //私有属性
    char *name;
    int age;
};

定义好了 构造函数,那如果使用呢

int main() {
    Student stu; //调用空参构造
    Student stud("林俊杰"); //调用一个参数的构造
    Student student("林俊杰",30); //调用两个参数的构造
    return 0;
}

我们来看看打印结果 看看是不是调用相应的构造函数


image.png

可以看到都调用了相应的构造函数. 我们看到因为name和age是私有属性,不能直接访问,如果我们想通过空参构造函数去设置name和age怎么办呢,其实跟java一样 可以在公有属性设置set方法和get方法来.

   //空参构造
    Student() {
        cout << "空参构造函数" << endl;
    }
    void setAge(int age) {
        this->age = age;
    }
    int getAge() {
        return this->age;
    }
    void setName(char *name) {
        this->name = name;
    }
    char *getName() {
        return this->name;
    }

然后通过调用set和get方法对属性进行赋值和取值;

  Student *s = new Student(); //调用空参构造
  s->setName("周杰伦");
  s->setAge(35);
  cout << "name = " << s->getName() << " age = "<< s->getAge()<< endl;

打印结果


image.png

在C++中也是栈区和堆区的概念,跟java比较像. 像上面一种方式就是在栈区开辟空间的 在main函数出栈后里面的资源都会被释放.
下面讲下通过堆区开辟空间

int main() {
    // TODO  =========== 下面是栈区 开辟空间的
    Student stu; //调用空参构造
    Student stud("林俊杰"); //调用一个参数的构造
    Student student("林俊杰",30); //调用两个参数的构造
    
    // TODO  =========== 下面是堆区 开辟空间的
    Student *s = new Student(); //调用空参构造
    Student *stu1 = new Student("杜子腾"); //调用一个参数的构造
    Student *stu2 = new Student("杜子腾", 26);  //调用两个参数的构造
    return 0;
}

堆区开辟空间是不是很java很像 都是通过new的方式.但是通过堆区开辟空间是要我们手动释放的,不然内存占用的会越来越多. 所以每次new完都要用delete关键字释放占用的内存.new和delete是成对出现的.

 Student *s = new Student(); //调用空参构造
    delete s;
    Student *stu1 = new Student("杜子腾"); //调用一个参数的构造
    delete stu1;
    Student *stu2 = new Student("杜子腾", 26);  //调用两个参数的构造
    delete stu2;

在这里扩展一下,有参构造有时候还有另外一种写法,你可能会在一些源码中看到这样的写法

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

在一些系统源码里面会有很多这样的写法 :name(name)等价this->name = name;
我们再来看下另外一种有意思写法:

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

我们在main方法是创建下构造函数 Student *stu1 = new Student("杜子腾");, 大家来猜一猜结果是怎么样的


image.png

打印结果是先调用了两个参数的构造函数,在调用的一个参数的构造函数.至于为什么会这样我也不是很清楚.
三、C++的析构函数
在学习析构函数之前我们先来了解下什么是析构函数,析构函数是用来做什么用的。
析构函数可以说构造函数Student对象的临终遗言,在Student对象被回收后,帮你做一些释放工作.
析构函数是用 ~符号修饰的 如下所示

  //析构函数    Student对象的临终遗言,Student对象被回收了,你做一些释放工作
    ~Student() {
        cout << "析构函数" << endl;
    }

我们在执行delete student对象的时候一定会调用析构函数 ,我们来在main方法里delete student'对象来试试析构函数是否会执行


image.png

我们可以看到执行了析构函数. 具体的用法就是我们在构造函数里面在堆区开辟空间,我delete student的时候就必须把在堆区开辟的空间释放,这时候用析构函数来释放占用内存. 例如下面
我们在两个参数的构造函数里面 在堆区开辟一个空间在析构函数中释放

  // 两个参数的构造函数
    Student(char *name, int age) {
        // this->name = name;
        // 堆区  malloc代表在堆区开辟空间
        this->name = (char *) (malloc(sizeof(char *) * 10));
        // 字符串拷贝api
        strcpy(this->name, name);

        this->age = age;
        cout << "两个参数的构造函数" << endl;
    }
    ~Student() {
        cout << "析构函数" << endl;
        // 必须释放 堆区开辟的成员
        if (this->name) {
            free(this->name);
            this->name = NULL; // 执行NULL的地址,避免出现悬空指针
        }
    }

四、拷贝构造函数
在了解什么是拷贝构造函数之前我们先来看一段代码

int main() {
    Student student ("刘德华",50);
    Student  student1 = student;
    cout << "student1的name = " <<student1->getName() <<" age =  "<< student1->getAge() << endl;
    return 0;
}

猜一猜这样打印student1的name和age是否有值.


image.png

打印结果是有值的,但是为什么呢. 这个就是C++的拷贝构造函数,在我们看不到地方C++已经帮我们作了一些工作,它会先去找student对应属性的值,在把这些值赋值给student1对应的属性.
拷贝构造函数是隐式的,C++已经默认帮我实现了, 但是我也可以覆盖拷贝函数,实现自己想要的拷贝函数,怎么做呢.

   // 覆盖拷贝构造函数
    Student(const Student & student) { // 常量引用:只读的,不让你修改
        cout << "拷贝构造函数" << endl;
        // 我们自己赋值
        // 为什么要自己赋值,自己来控制,就可以 例如:-10
        this->name = student.name;
        this->age = student.age - 10;
        cout << "自定义拷贝构造函数 内存地址 " << &student << endl;
    }

覆盖拷贝构造函数后 我们重新来执行下刚才代码 看看结果


image.png

可以看到age的值为40,而且拷贝构造函数也执行了
我接下来看另外一个段代码 大家猜下age会不会减10;

 Student *student1 = new Student("刘德华", 50);
 Student *student2 = student1; 
cout << "student1的name = " <<student1->getName() <<" age =  "<< student1->getAge() << 
image.png

结果没有减10 而且拷贝构造函数也没有执行这是为什么呢?
大家看下这段断代码 Student *student2 = student1; 有没有发现段代码其实是定义了一个student2 指针指向student1指针所对应的地址,而不是拷贝函数,就明白为什么没有减10 拷贝函数也为什么没有执行.

五、常量指针、指针常量、常量指针常量
1.常量指针


image.png

常量指针不允许去修改【常量指针】存放地址所对应的值, 允许重新指向【常量指针】存放的地址
按我的理解就是常量对应指针的地址是不能变的 所以叫常量指针(常量的对应的地址或者指针不能变)
2.指针常量


image.png

指针常量 允许去修改【指针常量】存放地址所对应的值 ,不允许重新指向【指针常量】存放的地址
按我的理解就是指针的地址不能变,指针是个常量.
3.常量指针常量
image.png

常量指针常量 不允许去修改【常量指针常量】存放地址所对应的值也不允许重新指向【常量指针常量】存放的地址 就是指针是常量 指针对应的值也是常量 两个定死了 都不能修改.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容