布局文件:
<?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
整理自示例代码