C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++ this原理

C++ this原理与可变参数及友元函数友元类分步详解用法

作者:lpf_wei

可变参数模板(variadic templates)是C++11新增的强大的特性之一,它对模板参数进行了高度泛化,能表示0到任意个数、任意类型的参数,这篇文章主要介绍了C++ this原理与可变参数及友元函数友元类

1.c++可变参数的应用

#include <iostream>
#include <stdarg.h>  //可变参数的支持
using namespace std;
void add(int count,...){
    va_list vp; 
    va_start(vp, count);
    // 取出可变参数的一个值
    int number  = va_arg(vp, int);
    cout << number << endl;
    // 取出可变参数的一个值
    number  = va_arg(vp, int);
    cout << number << endl;
    // 取出可变参数的一个值
    number  = va_arg(vp, int);
    cout << number << endl;
    // 越界之后取出来的是0
    number  = va_arg(vp, int);
    cout << number << endl;
    // 关闭阶段
    va_end(vp);
}
int main() {
    add(546, 6,7,8);
    return 0;
}

日志输出:
/home/ms/workspace/study/ndk/CPlusStudy/cmake-build-debug/CPlusStudy
可变参数输出
6
7
8
0

项目中的应用:

int add(int count,...){
    va_list va;
    va_start(va,count);
    for (int i = 0; i < count; ++i) {
        int number=va_arg(va,int);
        cout << number << endl;
    }
    va_end(va);
}
int main() {
    std::cout << "可变参数输出" << std::endl;
    add(3, 6,7,8);
    return 0;
}

日志输出:
可变参数输出
6
7
8

第一个参数count可以作为可变参数的数量。

2.static 静态变量与静态方法

class Douluo {
public:
//    static char * name="唐三";  静态变量不能直接初始化  编译不通过
    static char * name;
    Douluo() {
//         name="唐三";  //静态变量不能在构造方法初始化
    }
    static void update() {
//        name="唐三"; //静态变量不能在静态方法初始化
        cout<<"name="<<name<<endl;
    }
    void update2() {
        // 运行报错
//         name="唐三";  //静态变量不能在非静态方法初始化
    }
};
/*静态变量正确初始化姿势*/
char* Douluo::name="唐三";
int main() {
//    std::cout << "可变参数输出" << std::endl;
//    add(3, 6,7,8);
    std::cout << "static的应用" << std::endl;
    Douluo douluo;
//    Douluo::name="唐三";  //静态变量不能在main方法初始化 会报错
    douluo.update2();
    Douluo::update(); // 类名::可以调用静态函数  调用静态方法的正确姿势
    return 0;
}

通过实际操作可知:

3.常量指针与指针常量

int * const 指针常量 指针常量【地址对应的值能改,地址不可以修改】

const int * 常量指针 常量指针【地址可以修改,地址对应的值不能改】

this : 本质上就是指针常量

    // 默认现在:this 等价于 const Student * const  常量指针常量(地址不能改,地址对应的值不能改)
    void changeAction() const {
        // 地址不能改
//         this = 0x43563;
        // 地址对应的值不能改
//         this->age = 80;
    }
```### Android NDK篇-C++语言之 this 原理和可变参数与友元函数友元类
#### 1.c++可变参数的应用
```c++
#include <iostream>
#include <stdarg.h>  //可变参数的支持
using namespace std;
void add(int count,...){
    va_list vp; 
    va_start(vp, count);
    // 取出可变参数的一个值
    int number  = va_arg(vp, int);
    cout << number << endl;
    // 取出可变参数的一个值
    number  = va_arg(vp, int);
    cout << number << endl;
    // 取出可变参数的一个值
    number  = va_arg(vp, int);
    cout << number << endl;
    // 越界之后取出来的是0
    number  = va_arg(vp, int);
    cout << number << endl;
    // 关闭阶段
    va_end(vp);
}
int main() {
    add(546, 6,7,8);
    return 0;
}

日志输出:
/home/ms/workspace/study/ndk/CPlusStudy/cmake-build-debug/CPlusStudy
可变参数输出
6
7
8
0

项目中的应用:

int add(int count,...){
    va_list va;
    va_start(va,count);
    for (int i = 0; i < count; ++i) {
        int number=va_arg(va,int);
        cout << number << endl;
    }
    va_end(va);
}
int main() {
    std::cout << "可变参数输出" << std::endl;
    add(3, 6,7,8);
    return 0;
}

日志输出:
可变参数输出
6
7
8

第一个参数count可以作为可变参数的数量。

4.static 静态变量与静态方法

class Douluo {
public:
//    static char * name="唐三";  静态变量不能直接初始化  编译不通过
    static char * name;
    Douluo() {
//         name="唐三";  //静态变量不能在构造方法初始化
    }
    static void update() {
//        name="唐三"; //静态变量不能在静态方法初始化
        cout<<"name="<<name<<endl;
    }
    void update2() {
        // 运行报错
//         name="唐三";  //静态变量不能在非静态方法初始化
    }
};
/*静态变量正确初始化姿势*/
char* Douluo::name="唐三";
int main() {
//    std::cout << "可变参数输出" << std::endl;
//    add(3, 6,7,8);
    std::cout << "static的应用" << std::endl;
    Douluo douluo;
//    Douluo::name="唐三";  //静态变量不能在main方法初始化 会报错
    douluo.update2();
    Douluo::update(); // 类名::可以调用静态函数  调用静态方法的正确姿势
    return 0;
}

通过实际操作可知:

5.常量指针与指针常量

int * const 指针常量 指针常量【地址对应的值能改,地址不可以修改】

const int * 常量指针 常量指针【地址可以修改,地址对应的值不能改】

this : 本质上就是指针常量

    // 默认现在:this 等价于 const Student * const  常量指针常量(地址不能改,地址对应的值不能改)
    void changeAction() const {
        // 地址不能改
//         this = 0x43563;
        // 地址对应的值不能改
//         this->age = 80;
    }

方法名后边添加const 符号,表示的意思是常量指针常量,这个情况下值不能改,地址也不能改。

6.friend 友元函数

class Person {
private: // 私有的age,外界不能访问
    int age = 0;
public:
    Person(int age) {
        this->age = age;
    }
    int getAge() {
        return this->age;
    }
    // 定义友元函数 (声明,没有实现)
    friend void updateAge(Person * person, int age);
};
// 友元函数的实现,可以访问所以私有成员
void updateAge(Person* person, int age) {
    // 默认情况下:不能修改 私有的age
    // 谁有这个权限:友元(拿到所有私有成员)
    person->age = age;
}
int main(){
    Person person = Person(30);
    updateAge(&person, 31);
    cout << person.getAge() << endl;
}

日志输出:
/home/ms/workspace/study/ndk/CPlusStudy/cmake-build-debug/CPlusStudy
31

友元函数是为了私有成员在没有set方法的情况下,可以通过友元函数来访问私有成员变量。

7.友元类

class ImageView {
private:
    int viewSize;
    friend class Class; // 友元类
};
// Java每个类,都会有一个Class,此Class可以操作 ImageView私有成员(感觉很神奇)
class Class {
public:
    ImageView imageView;
    void changeViewSize(int size) {
        imageView.viewSize = size;
    }
    int getViewSize() {
        return imageView.viewSize;
    }
};
int main(){
    Class mImageViewClass;
    mImageViewClass.changeViewSize(600);
    cout << mImageViewClass.getViewSize() << endl;
}

Java每个类,都会有一个Class,此Class可以操作 ImageView私有成员,友元类就类比Java的中的Class,如果去掉friend,就不能访问ImageView的成员了。

方法名后边添加const 符号,表示的意思是常量指针常量,这个情况下值不能改,地址也不能改。

8.friend 友元函数

class Person {
private: // 私有的age,外界不能访问
    int age = 0;
public:
    Person(int age) {
        this->age = age;
    }
    int getAge() {
        return this->age;
    }
    // 定义友元函数 (声明,没有实现)
    friend void updateAge(Person * person, int age);
};
// 友元函数的实现,可以访问所以私有成员
void updateAge(Person* person, int age) {
    // 默认情况下:不能修改 私有的age
    // 谁有这个权限:友元(拿到所有私有成员)
    person->age = age;
}
int main(){
    Person person = Person(30);
    updateAge(&person, 31);
    cout << person.getAge() << endl;
}

日志输出:
/home/ms/workspace/study/ndk/CPlusStudy/cmake-build-debug/CPlusStudy
31

友元函数是为了私有成员在没有set方法的情况下,可以通过友元函数来访问私有成员变量。

9.友元类

class ImageView {
private:
    int viewSize;
    friend class Class; // 友元类
};
// Java每个类,都会有一个Class,此Class可以操作 ImageView私有成员(感觉很神奇)
class Class {
public:
    ImageView imageView;
    void changeViewSize(int size) {
        imageView.viewSize = size;
    }
    int getViewSize() {
        return imageView.viewSize;
    }
};
int main(){
    Class mImageViewClass;
    mImageViewClass.changeViewSize(600);
    cout << mImageViewClass.getViewSize() << endl;
}

Java每个类,都会有一个Class,此Class可以操作 ImageView私有成员,友元类就类比Java的中的Class,如果去掉friend,就不能访问ImageView的成员了。

到此这篇关于C++ this原理与可变参数及友元函数友元类分布详解用法的文章就介绍到这了,更多相关C++ this原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文