NDK-CPP语言-模版类运算符重载+模版类static关键字+类型转换

46 篇文章 1 订阅
42 篇文章 0 订阅

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.tz.ndk.cpp.MainActivity"
    android:orientation="vertical">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="1.C++语言:模版类中重载运算符"
        android:onClick="clickCppTempClassOverloadOp"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="2.C++语言:模版类中使用static修饰符"
        android:onClick="clickCppTempClassStatic"/>


    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="3.C++语言:模版类模拟Java中的List集合"
        android:onClick="clickCppTempClassList"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="4.C++语言:类型转换"
        android:onClick="clickCppTypeConversion"/>

</LinearLayout>

java代码:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    static {
        System.loadLibrary("native-lib");
    }

    private NDKCpp ndkCpp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ndkCpp = new NDKCpp();

        //Java中
        //Java中ArrayList.remove方法操作数组,本质上就是通过NDK(C/C++)实现
        ArrayList<Integer> array = new ArrayList<Integer>();
        array.add(0,100);
        array.add(1,200);
        array.add(2,300);

        array.remove(0);
        array.get(0);
    }

    public void clickCppTempClassOverloadOp(View v){
        ndkCpp.callCppTempClassOverloadOp();
    }

    public void clickCppTempClassStatic(View v){
        ndkCpp.callCppTempClassStatic();
    }

    public void clickCppTempClassList(View v){
        ndkCpp.callCppTempClassList();
    }

    public void clickCppTypeConversion(View v){
        ndkCpp.callCppTypeConversion();
    }

}

public class NDKCpp {

    //1.C++语言:模版类中重载运算符
    public native void callCppTempClassOverloadOp();

    //2.C++语言:模版类中使用static修饰符
    public native void callCppTempClassStatic();

    //3.C++语言:模版类模拟Java中的List<T>集合
    public native void callCppTempClassList();

    //4.C++语言:类型转换
    public native void callCppTypeConversion();

}

c代码:

com_tz_ndk_cpp_NDKCpp.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_tz_ndk_cpp_NDKCpp */

#ifndef _Included_com_tz_ndk_cpp_NDKCpp
#define _Included_com_tz_ndk_cpp_NDKCpp
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_tz_ndk_cpp_NDKCpp
 * Method:    callCppTempClassOverloadOp
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppTempClassOverloadOp
  (JNIEnv *, jobject);

JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppTempClassStatic
        (JNIEnv *, jobject);

JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppTempClassList
        (JNIEnv *, jobject);

JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppTypeConversion
        (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
com_tz_ndk_cpp_NDKCpp.cpp

#include <iostream>
#include <android/log.h>

#include "com_tz_ndk_cpp_NDKCpp.h"

using namespace std;


//1.C++语言:模版类中重载运算符
//#include "Company.cpp"
//#include "Student.hpp"
//#include "Test.cpp"
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppTempClassOverloadOp
        (JNIEnv *, jobject){
//    Company<int> company(100);
//    Company<int> company1(200);
//    Company<int> company2 = company - company1;
//    __android_log_print(ANDROID_LOG_INFO,"main","值:%d",company2.t);


//    Student<int> company(100);
//    Student<int> company1(200);
//    Student<int> company2 = company - company1;
//    __android_log_print(ANDROID_LOG_INFO,"main","值:%d",company2.t);


//    Test<int> company(100);
//    Test<int> company1(200);
//    Test<int> company2 = company - company1;
//    __android_log_print(ANDROID_LOG_INFO,"main","值:%d",company2.t);
}



//2.C++语言:模版类中使用static修饰符
#include "Company.h"

//注意:初始化静态变量
//template <typename T>
//T Company<T>::t = NULL;

JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppTempClassStatic
        (JNIEnv *, jobject){
    //相同类型
    //静态变量属于类(共享)
    //总结:相同类型模版类共用静态属性
//    Company<int> company1(100);
//    company1.t++;
//    __android_log_print(ANDROID_LOG_INFO,"main","值:%d",company1.t);
//
//    Company<int> company2(200);
//    company2.t++;
//    __android_log_print(ANDROID_LOG_INFO,"main","值:%d",company1.t);
//    __android_log_print(ANDROID_LOG_INFO,"main","值:%d",company2.t);

    //不同类型
    //总结:不同类型模版类不共享静态属性
//    Company<int> company1(100);
//    company1.t++;
//    __android_log_print(ANDROID_LOG_INFO,"main","值:%d",company1.t);
//
//    Company<char> company2('A');
//    company2.t++;
//    __android_log_print(ANDROID_LOG_INFO,"main","值:%d",company1.t);
//    __android_log_print(ANDROID_LOG_INFO,"main","值:%c",company2.t);
}


//3.C++语言:模版类模拟Java中的List<T>集合
#include "ArrayList.h"
#include "Company.h"
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppTempClassList
        (JNIEnv *, jobject){
//    ArrayList<int>* arrayList = new ArrayList<int>(5);
//    arrayList->add(0,100);
//    arrayList->add(1,200);
//    arrayList->add(2,300);
//    arrayList->add(3,400);
//    arrayList->add(4,500);
//
//    for (int i = 0; i < arrayList->size(); ++i) {
//        int result = arrayList->get(i);
//        __android_log_print(ANDROID_LOG_INFO,"main","第%d值:%d",i,result);
//    }
//
//
//    int result = arrayList->remove(2);
//    __android_log_print(ANDROID_LOG_INFO,"main","当前删除的元素:%d",result);
//    __android_log_print(ANDROID_LOG_INFO,"main","当前数组的大小:%d",arrayList->size());


    //重载运算符'='
//    ArrayList<int> arrayList = ArrayList<int>(5);
//    arrayList.add(0,100);
//    arrayList.add(1,200);
//    arrayList.add(2,300);
//    arrayList.add(3,400);
//    arrayList.add(4,500);
//
//    //拷贝
    ArrayList<int> array1 = arrayList;
    for (int i = 0; i < array1.size(); ++i) {
        int result = array1.get(i);
        __android_log_print(ANDROID_LOG_INFO,"main","第%d值:%d",i,result);
    }
//
//    //对象存在
//    ArrayList<int> array1 = ArrayList<int>(1);
//    array1 = arrayList;
//    for (int i = 0; i < array1.size(); ++i) {
//        int result = array1.get(i);
//        __android_log_print(ANDROID_LOG_INFO,"main","第%d值:%d",i,result);
//    }

    //保存对象
//    ArrayList<Company> arrayList = ArrayList<Company>(3);
//    Company company1 = Company("潭州教育",10);
//    Company company2 = Company("阿里巴巴",17);
//    Company company3 = Company("腾讯",17);
//    arrayList.add(0,company1);
//    arrayList.add(1,company2);
//    arrayList.add(2,company3);
//    for (int i = 0; i < arrayList.size(); ++i) {
//        Company result = arrayList.get(i);
//        __android_log_print(ANDROID_LOG_INFO,"main","第%d名字:%s",i,result.name);
//    }
//
//
//    //深拷贝-对象
//    ArrayList<Company> array1 = ArrayList<Company>(1);
//    array1 = arrayList;
}



//4.C++语言:类型转换
//4.1 静态类型转换:static_cast
//使用场景:static_cast
//4.1.1 用于类层次结构(继承),基类和子类之间指针和引用转换
//4.1.2 用于基本数据类型的转换(例如:int、double......)
//4.1.3 把void指针转成目标类型的指针(不安全)
//注意:大类型转小类型,数据会丢失

//4.2 常量类型转换:const_cast
//使用场景:主要用于常量指针转成非常量指针

//4.3 强制类型转换:reinterpret_cast
//使用场景:允许任何指针类型转为其他类型指针

//4.4 动态类型转换
//使用场景:主要用于类的继承体系中(类层次结构),还可以用于类之间的交叉转换
//void func(Company* company){
//    TzCompany* tzCompany = dynamic_cast<TzCompany*>(company);
//    if(tzCompany != NULL){
        __android_log_print(ANDROID_LOG_INFO,"main","姓名:%s",tzCompany->name);
//    }
//}

JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppTypeConversion
        (JNIEnv *, jobject){
    //普通写法
//    int a = 100;
//    //自动转换(系统自动帮助转类型)
//    double b = a;
//    //强制类型转换
//    double d = (double)a;

    //采用C++中提供函数库
    //4.1 静态类型转换
//    int a = 100;
//    double b = 10.5;
//    b = static_cast<double>(a);

    //4.1.1 用于类层次结构(继承),基类和子类之间指针和引用转换
//    Company company = TzCompany("潭州教育",9);
//    //TzCompany&:代表引用
//    TzCompany tzCompany = static_cast<TzCompany&>(company);
//    //报错
    tzCompany = company;
//    __android_log_print(ANDROID_LOG_INFO,"main","名称:%s",tzCompany.name);


    //4.2 常量类型转换
//    int a = 100;
//    int b = 1200;
//    //常量指针和指针常量
//    //常量指针:指针指向的地址对应的值不能够修改,但是指针指向的地址可以修改
//    //指针常量:
//    const Company *company = new Company("潭州",9);
//    //一下写法报错
    Company* company1 = company;
//    Company* company1 = const_cast<Company*>(company);


    //4.3 强制类型转换:reinterpret_cast
    //使用场景:允许任何指针类型转为其他类型指针
//    Company* company = new Company("潭州",9);
//    TzCompany* student = reinterpret_cast<TzCompany*>(company);
//    __android_log_print(ANDROID_LOG_INFO,"main","姓名:%s",student->name);
//    //自己手动强制类型转换
//    student = (Student*)company;


    //4.4 动态类型转换
    //使用场景:主要用于类的继承体系中(类层次结构),还可以用于类之间的交叉转换
    //语法需要注意
    //下一节课解决:童鞋们可以课后试一下
//    TzCompany company;
//    Company* company1 = &company;
//    func(company1);
}




ArrayList.h

#ifndef DREAM_NDK_CPP_11_12_20_ARRAYLIST_H
#define DREAM_NDK_CPP_11_12_20_ARRAYLIST_H

#include <iostream>

//Java中ArrayList.remove方法操作数组,本质上就是通过NDK(C/C++)实现
template <typename T>
class ArrayList{
private:
    int len;
    //保存的是数组的首地址
    T* array = NULL;
public:
    //构造方法
    ArrayList(int len){
        this->len = len;
        //动态创建数组(动态分配内存)
        //C++中写法
        this->array = new T[len];
    }
    //析构函数
    ~ArrayList(){
        if(this->array != NULL){
            delete[] this->array;
            this->array = NULL;
        }
    }
    //获取数组的大小
    int size(){
        return this->len;
    }
    //添加元素
    void add(int index,T &value){
        //防止数组越界
        if (index > this->len){
            index = this->len - 1;
        }
        this->array[index] = value;
    }
    //获得指定元素
    T& get(int index){
        return this->array[index];
    }
    //删除元素
    T& remove(int index){
        //第一步:创建新的数组(另外一种方案: 指针位移)
        int j = 0;
        int newLen = this->len - 1;
        T* newArray = new T[newLen];
        T result = NULL;
        //第二步:将原始数组中的原始拷贝到新的数组中
        //实现:如果i==index就不是我需要的元素
        for (int i = 0; i < this->len; ++i) {
            if (i != index){
                //不需要删除的元素
                newArray[j] = this->array[i];
                j++;
            }else{
                //删除元素
                result = this->array[i];
            }
        }

        //第三步:释放原始数组内存
        //这样的做法很容易内存泄漏
//        this->array = newArray;
        if(this->array != NULL){
            delete[] this->array;
            this->array = NULL;
        }

        //第四步:重新赋值
        this->array = newArray;
        this->len = newLen;
        return result;
    }

    //实现拷贝函数
    ArrayList(const ArrayList<T> &arrayList){
        //拷贝
        if(this->array != NULL){
            delete[] this->array;
            this->array = NULL;
        }
        this->len = arrayList.len;
        this->array = new T[this->len];
        for (int i = 0; i < this->len; ++i) {
            this->array[i] = arrayList.array[i];
        }
    }

    //重载运算符'='
    ArrayList<T>& operator=(const ArrayList<T> &arrayList){
        //拷贝
        if(this->array != NULL){
            delete[] this->array;
            this->array = NULL;
        }
        this->len = arrayList.len;
        this->array = new T[this->len];
        for (int i = 0; i < this->len; ++i) {
            this->array[i] = arrayList.array[i];
        }
        return (*this);
    }

};

#endif

Company.h

#ifndef DREAM_NDK_CPP_11_12_20_COMPANY_H
#define DREAM_NDK_CPP_11_12_20_COMPANY_H

#include <iostream>

using namespace std;

//1.C++语言:模版类中重载运算符
//1.1 申明和实现在一个文件中
//typename和class基本上是相同用法
//template <typename T>
//class Company{
//public:
//    T t;
//public:
//    Company(T t){
//        this->t = t;
//    }
//
//    //重载'+'运算符
//    //常规写法
    Company operator+(Company &company){
        this->t = this->t + company.t;
        return (*this);
    }
//
//    //结合模版函数重载运算符
//    //重载'+'号
//    Company<T> operator+(Company<T> &company){
//        this->t = this->t + company.t;
//        return (*this);
//    }
//    //重载'-'号
//    Company<T> operator-(Company<T> &company){
//        this->t = this->t - company.t;
//        return (*this);
//    }
//
//};

//1.2 实现和申明分开
//注意:如果你的类为模版类或者模版函数,
//     并且你的申明和实现在不同的文件,那么你在使用的时候,需要引入实现文件(不推荐使用)
//总结:所以我们的模版类或者模版函数的申明和实现需要在一个文件中
//建议:定义在同一个文件中
//class Company{
//public:
//    T t;
//public:
//    Company(T t);
//    //重载'+'号
//    Company<T> operator+(Company<T> &company);
//    //重载'-'号
//    Company<T> operator-(Company<T> &company);
//};



//2.C++语言:模版类中使用static修饰符
//template <typename T>
//class Company{
//public:
//    static T t;
//public:
//    Company(T t){
//        this->t = t;
//    }
//};


//3.C++语言:模版类模拟Java中的List<T>集合
//class Company{
//public:
//    int age;
//    char* name = NULL;
//public:
//    Company(){
//
//    }
//    Company(char* name,int age){
//        this->name = name;
//        this->age = age;
//
//        //给我们的name属性动态分配内存
//        int len = strlen(name);
//        this->name = new char[len];
//        strcpy(this->name,name);
//    }
//
//    //深拷贝
//    Company(const Company &company){
//        //释放内存
//        if(this->name != NULL){
//            delete[] this->name;
//            this->name = NULL;
//        }
//        int len = strlen(company.name);
//        this->name = new char[len];
//        strcpy(this->name,company.name);
//
//        this->age = company.age;
//    }
//
//    //析构函数释放内存
//    ~Company(){
//        if(this->name != NULL){
//            delete[] this->name;
//            this->name = NULL;
//        }
//    }
//};



//4.C++语言:类型转换
class Company{
//public:
//    int age;
//    char* name = "Dream";
public:

    Company(){

    }

//    Company(char* name,int age){
//        this->name = name;
//        this->age = age;
//    }
};

class TzCompany : virtual public Company{
public:

    TzCompany(){

    }

//    TzCompany(char* name,int age) : Company(name,age){
//
//    }
};

class Student{
public:
    char*name;
public:
    Student(){
        this->name = "Dream";
    }
};



#endif 

Company.cpp

#include "Company.h"

using namespace std;

//注意:T的作用域只在当前函数中
//template <typename T>
//Company<T>::Company(T t) {
//    this->t = t;
//}
//
//template <typename T>
//Company<T> Company<T>::operator+(Company<T> &company) {
//    this->t = this->t + company.t;
//    return (*this);
//}
//
//template <typename T>
//Company<T> Company<T>::operator-(Company<T> &company) {
//    this->t = this->t - company.t;
//    return (*this);
//}

Student.hpp

#ifndef DREAM_NDK_CPP_11_12_20_STUDENT_H
#define DREAM_NDK_CPP_11_12_20_STUDENT_H

#include <iostream>
using namespace std;


//注意:在Visual Studio 2013中是可以的
//课后可以测试一下
//在AS里面编译可以
//-------------申明---------------//
template <typename T>
class Student{
public:
    T t;
public:
    Student(T t);
    //重载'+'号
    Student<T> operator+(Student<T> &company);
    //重载'-'号
    Student<T> operator-(Student<T> &company);
};


//------------实现---------------//
template <typename T>
Student<T>::Student(T t) {
    this->t = t;
}

template <typename T>
Student<T> Student<T>::operator+(Student<T> &company) {
    this->t = this->t + company.t;
    return (*this);
}

template <typename T>
Student<T> Student<T>::operator-(Student<T> &company) {
    this->t = this->t - company.t;
    return (*this);
}

#endif 


整理自示例代码



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值