C++11笔记

C++引用和指针和void

int  int_b = 124; 
int *int_b_ptr = &int_b;
int &int_c = int_b;
*int_b_ptr=126;
cout<<int_b;
int_c=128;
cout<<int_b;

 最后分别打印126 128

引用和指针在某种程度上没有区别。

void:代表空类型,也就是无类型,只能用于定义指针变量,如void*,当定义了void *p=xxx时,可以通过sizeof(p)是否为4或者8来判断当前运行模式

nullptr

目的:解决NULL带来的二义性问题

void func(int){

count<<"1";

}

void func(int*){

count<<"2";

}

func(NULL) 最后打印1;

func(nullptr)最后打印2;

NULL定义

#define NULL 0 

C++11中的结构体和对象

C中的结构体的定义只包含属性而不能有函数的声明和定义,C++11中的结构体扩展了C中的结构体的概念(可以把C++11的类看成对C的结构体的扩展),既可以有属性,又可以有函数。而对于C++11中的结构体和对象,当被编译器编译之后,其实就跟C中的结构体没有区别了

C++11中其他关键字

auto为C++11中的类型推导关键字

C++98/03中auto关键字用于标识具有自动存储期的局部变量,作用不大。比如auto int a =0,它在C++98/03和int a =0一样的,一般都省略掉了auto 关键字,与之相对的static int a =0;标识a是一个静态类型,存储在堆的全局数据区。

C++11中 auto a =20 和 int a=20一样。但是使用auto 变量必须初始化。 

auto pi= new auto(1) //pi是int *型指针

const auto *v =&a,u =6 // v是const int *类型static  u 是const int 类型

auto限制:

1、auto不能作为函数参数

void func(auto a = 1) {
    __android_log_print(4, "CPP11", "func is called");
}

2、auto不能修饰类或者结构体中的非静态成员变量

struct Mystruct {
    //auto var = 1;
//static auto var2 = 2;
//error: auto不能修饰类或者结构体中的非静态成员
    const static auto var2 = 2;
};

3、auto不能定义数组

4、auto不能推导出模板参数

decltype关键字

用于在编译时期推导出一个表达式的类型,而不需要初始化,语法格式有点像sizeof,

decltype(a);

a=22; //int


float float_b = 0.2;
decltype(int_tmp * float_b) tmp_b; //float


int add(int a ,int b){
return a+b
}
decltype(add(5,6)) tmp_bb; //int 但是tmp_bb没有被初始化,值不确定

ART下C++11中类、函数以及访问权限

public:可以被任意对象访问

protected:只允许子类以及本类的成员函数访问

private:只允许本类的成员函数访问

继承

public继承,private继承,protected继承

派生类能且只能访问基类的public和protected成员,默认继承方式是private

基类中继承方式子类中public & public继承=> public

访问权限
组合结果
基类中  & 继承方式子类中

public & public继承=> public
public & protected继承=> protected

public & private继承= > private

protected & public继承=> protected

protected & protected继承=> protected

protected & private继承= >private

private & public继承=>子类无权访问
private & protected继承>子类无权访问究;

private & private继承=>子类无权访问

private & protected继承>子类无权访问究;

private & private继承=>子类无权访问

由以上组合结果可以看出

1、public继承不改变基类成员的访问权限

2、private继承使得基类所有成员在子类中的访问权限变为private

3、protected继承将基类中public成员变为子类的protected成员,其它成员的访问权限不变。

4、基类中的private成员不受继承方式的影响,子类永远无权访问。此外,在使用private继承时,还存在另外一种机制:准许访问

我们已经知道,在基类以private方式被继承时,其public和protected成员在子类中变为private成员。然而某些情况下,需要在子类中将一个或多个继承的成员恢复其在基类中的访问权限。

友元函数和友元类(理解为朋友关系)

私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进仃。这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦。因此,C++就有了友元(friend)的概念。打个比方,这相当于是说:朋友是值得信任的,所以可以对他们公开一些自己的隐私。

//person.h

#include "android/log.h"

class person {
private:
    int sex;
    int age;

    int getsexprivate() {
        return this->sex;
    }

protected:
    int getageprotected() {
        return this->age;
    }

public:
    person(int sex, int age) : sex(sex), age(age) {
        __android_log_print(4, "CPP11", "%s", "person(int sex,int age) is called");
    }
    virtual void test(){
        __android_log_print(4, "CPP11", "%s", "preson virtual test is called");
    }
    int getsex();

    int getage();

    void setsex(int sex);

    void setage(int age);

};

 

//student.h 默认方式继承
#include "person.h"
#include "android/log.h"


class student : person {
public:
    student(int sex, int age, int id) : person(sex, age) {
        this->id = id;
        __android_log_print(4, "CPP11", "%s", "student(int sex, int age,int id)");
    }

    virtual void test() {
        __android_log_print(4, "CPP11", "%s", "student virtual test is called");
    }

    int getid();

    void setid(int id);

    friend int getstuid(student *stu);

    friend class teacher;

private:
    int id;


};

int getstuid(student *stu);

 

//person.cpp
#include "person.h"
int person::getsex() {
    //return this->sex;
    return this->getsexprivate();
//访问private函数唯一途径
}

//int getage();
int person::getage() {
    return this->age;
}

void person::setage(int age) {
    this->age = age;
}

void person::setsex(int sex) {
    this->sex = sex;
}
//void setsex(int sex);

//void setage(int age);

 

//student.cpp
#include "student.h"

int getstuid(student *stu) {
    return stu->id;
}

//int getid();
int student::getid() {
    //return this->id;
    return getageprotected() + getsex();
}

//void setid(int id);
void student::setid(int id) {
    this->id = id;
}
#include "person.h"
  person man(0, 24);
    __android_log_print(4, "CPP11", "manage:%d", man.getage()); //24 

C++11中的模板函数和模板类

模板:泛型编程基础。即以一种独立任何特定类型的方式编写代码,ART中大量运用了模板

模板函数:

template <class T>

T add(T a,T b){

return a+b;

}

template <typename T>
T sub(T a ,T b){
return a-b;
}

int res= add(5,6);
int res1=sub(6,5);

float res_f=add(5.2f,5.3f);
auto  res_a=add(5.2f,5.3f);

  

模板类:

template <class M>
class com{
public:
com(M a ,M b ):a(a),b(b){};
M mul(){
return a*b
}
private:
M a;
Mb;
}


com <int> com_int(6,8);
auto res_int=com_int.mul();

Frida hook So模板类模板函数

function hooktemplate() {

    var Compute_int_con_addr = Module.getExportByName("libnative-lib.so", "_ZN7ComputeIiEC2Eii");
    var Compute_int_add_addr = Module.getExportByName("libnative-lib.so", "_ZN7ComputeIiE3addEv");
    var Compute_short_con_addr = Module.getExportByName("libnative-lib.so", "_ZN7ComputeIsEC2Ess");
    var Compute_short_add_addr = Module.getExportByName("libnative-lib.so", "_ZN7ComputeIsE3addEv");
    //console.log(Compute_int_con_addr);
    Interceptor.attach(Compute_int_con_addr, {
        onEnter: function (args) {

            this.Compute_ptr = ptr(args[0]);
            var a = args[1];
            var b = args[2];
            console.log("Compute<int> Compute(" + a + "," + b + ");");
            args[1] = ptr(777); //参数替换
            args[2] = ptr(222);

        }, onLeave: function (retval) {

            Memory.writeInt(this.Compute_ptr, 20);  //替换参数第二种
            Memory.writeInt(this.Compute_ptr.add(4), 40);
        }
    });
    Interceptor.attach(Compute_int_add_addr, {
        onEnter: function (args) {

            var Compute_ptr = ptr(args[0]);
            var a = Memory.readInt(Compute_ptr);
            var b = Memory.readInt(Compute_ptr.add(4));
            console.log("Compute<int> add(" + a + "," + b + ");")

        }, onLeave: function (retval) {
            //retval.replace(888);
        }
    });


}

C++11的lambda表达式

格式:[捕捉列表](参数)mutable->返回值类型(函数体)

 1、捕捉列表[]足lambda的引出符,捕捉列表能够捕捉上下文中的变量,来供lambda函数使用:

[var]表示以值传递方式捕机变量var,[=]表示值传递捕捉所有父作用域变量,[&var]表示以引用传递方式捕捉变量var,[&]表示引用传递捕捉所有父作用域变量,[this]表示值传递方式捕捉当前的this指针还有一些组合:

[=,&a]表示以引用传递方式捕捉a,值传递方式捕捉其他变量

注意:捕捉列表不允许变量重复传递,如:[=,aj]°6[&,&this],会引起编译时期的错误.

参数列表与普通函数的参数列表一致。如果不需要传递参数,可以联连同()一同【省略】。mutable可以取消Lambda的常量属性,因为Lambda默认是const属性; multable仅仅是让Lamdba函数体修改值传递的变量,但是修改后并不会影响外部的变量。

返回类型如果是void时,可以连->一起【省略】,如果返回类型很明确,可以省略,让编译器自动推倒类型。

函数体和普通函数一样,除了可以使用参数之外,还可以使用捕获的变量。

int b(){

int a =10;
auto add=[](int num)->int{
    int res=0;
    for(int i=0;i<num;i++){
    res=res+i;
}
return res;
};
int res =add(a);
//第二种:
int res=[](int num)->int{
    int res=0;
    for(int i=0;i<num;i++){
    res=res+i;
}
return res;
}(10);
//第三种
int res=[](int num){
    int res=0;
    for(int i=0;i<num;i++){
    res=res+i;
}
return res;
}(10);
//第四种:
int a =10;
int res=[a]{
    int res=0;
    for(int i=0;i<a;i++){
    res=res+i;
}
return res;
}();


}

int c(){
int a =10;
int  b=20;
auto change=[a]()mutable{//a的值不会被改变
    a=20;
    return a;
}


auto change=[&a]{
    a=20;
    return a;
}

auto change=[&]{
    a=20;
     b=30;
    return a+b;
}


}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值