NDK-CPP语言-纯虚函数+函数模版+模版类

来源:互联网 发布:java技术手册 第六版 编辑:程序博客网 时间:2024/04/30 06:17

布局文件:

<?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="clickCppSuperClassPointer"/>    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="2.C++中:纯虚函数(抽象类)"        android:onClick="clickCppPureVirtualFunc"/>    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="3.C++中:函数模版(类似于Java泛型)"        android:onClick="clickCppFuncTemplate"/>    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="4.C++中:函数模版机制(原理)"        android:onClick="clickCppFuncTemplatePrinciple"/>    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="5.C++中:模版类"        android:onClick="clickCppClassTemplate"/>    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="6.函数指针作为函数参数传递"        android:onClick="clickCppFuncPointerParam"/></LinearLayout>
java代码:


package com.tz.ndk.cpp;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;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();    }    public void clickCppSuperClassPointer(View v){        ndkCpp.callCppSuperClassPointer();    }    public void clickCppPureVirtualFunc(View v){        ndkCpp.callCppPureVirtualFunc();    }    public void clickCppFuncTemplate(View v){        ndkCpp.callCppFuncTemplate();    }    public void clickCppFuncTemplatePrinciple(View v){        ndkCpp.callCppFuncTemplatePrinciple();    }    public void clickCppClassTemplate(View v){        ndkCpp.callCppClassTemplate();    }    public void clickCppFuncPointerParam(View v){        ndkCpp.callCppFuncPointerParam();    }//    //java中的抽象类//    public abstract class Test {//        public abstract void tet();//    }////    public class TestOne extends Test{////        @Override//        public void tet() {////        }////    }    //Java中方法泛型定义    //最小值//    public void getMin(int a,int b){////    }//    public void getMin(float a,float b){////    }//    public void getMin(double a,double b){////    }////    public <T> void getMin(T a,T b){////    }////    //getMin(10.23,20.354);    //在Java中//    class BaseDao<T>{//        private T t;//        public BaseDao(T t){//            this.t = t;//        }//    }//    class UserDao extends BaseDao<Integer>{//        public UserDao(Integer value){//            super(value);//        }//    }    //这个是Java中这样做    class BaseDao<T>{        private T t;        public BaseDao(T t){            this.t = t;        }    }    class UserDao<T> extends BaseDao<T>{        public UserDao(T value){            super(value);        }    }    class AndroidUserDao extends UserDao<Integer>{        public AndroidUserDao(Integer value){            super(value);        }    }}
public class NDKCpp {    //1.C++中:父类类型指针一些注意问题    public native void callCppSuperClassPointer();    //2.C++中:纯虚函数(抽象类)    public native void callCppPureVirtualFunc();    //3.C++中:函数模版(类似于Java泛型)    public native void callCppFuncTemplate();    //4.C++中:函数模版机制(原理)    public native void callCppFuncTemplatePrinciple();    //5.C++中:模版类    public native void callCppClassTemplate();    //6.函数指针作为函数参数传递    public native void callCppFuncPointerParam();}
c代码:

Company.h

#ifndef DREAM_NDK_CPP_11_11_19_COMPANY_H#define DREAM_NDK_CPP_11_11_19_COMPANY_H#import <android/log.h>//1.C++中:父类类型指针一些注意问题//1.1 回顾//class Company{//public://    //发工资//    virtual void salary(){//        __android_log_print(ANDROID_LOG_INFO,"main","发工资");//    }//};//class AliCompany : public Company{//public://    //发工资//    virtual void salary(){//        __android_log_print(ANDROID_LOG_INFO,"main","阿里巴巴发工资");//    }//};//1.2 分析对象大小//class Company{//private://    //公司名称//    char* name;//public://    //发工资(普通函数)//    virtual void salary(){//        __android_log_print(ANDROID_LOG_INFO,"main","发工资");//    }////    //招聘//    virtual void recruitment(){//        __android_log_print(ANDROID_LOG_INFO,"main","招聘");//    }////};//1.3 分析对象数组存在的一些问题//class Company{//public://    //公司名称//    char* name;//public:////    Company(char* name){//        this->name = name;//    }////    //发工资(普通函数)//    virtual void salary(){//        __android_log_print(ANDROID_LOG_INFO,"main","发工资");//    }////};//class TzCompany : public Company{//private://    int age;//public://    TzCompany(char* name,int age) : Company(name){//        this->age = age;//    }//    virtual void salary(){//        __android_log_print(ANDROID_LOG_INFO,"main","潭州发工资......");//    }//};//2.C++中:纯虚函数(java中的抽象类)//在Java中//为什么要使用抽象类?//总结:本质核心就是为了完善多态//通俗:约束和标准//今天在C++中//2.1 语法定义//class Company{//public:////    //虚函数定义////    virtual void salary(){////////    }//    //申明纯虚函数//    virtual void salary() = 0;//};//class TzCompany : public Company{//public://    //注意:你不实现语法检测不报错,但是编译报错//    //实现//    void salary(){//        __android_log_print(ANDROID_LOG_INFO,"main","潭州发工资......");//    }//};//2.2 C++中有没有类似Java的接口定义?//其实C++中的接口你可以用纯虚函数模拟(可以将C++类中的方法都申明为纯虚函数,也就类似与java中的接口)//C++中可以支持多继承//例如://class Company{//public://    virtual void salary() = 0;//    virtual void recruitment() = 0;//};//5.C++中:模版类(Java里面OrmLite、GreenDao(都是数据库))//5.1 语法定义//以下就是模版类的定义: template <class T>//其实也就类似于Java中的类泛型//template <class T>//class BaseDao{//private://    T t;//public://    BaseDao(T t){//        this->t = t;//    }//};////class UserDao : public BaseDao<int>{//public://    UserDao(int value) : BaseDao<int>(value){////    }//};//5.2 父类是模版类,子类也是模版类//template <class T>//class BaseDao{//private://    T t;//public://    BaseDao(T t){//        this->t = t;//    }//};//申明类型(子类)//架构师讲解的MVP架构设计(里面都是泛型)//template <typename T>//class UserDao : public BaseDao<T>{//public://    UserDao(T value) : BaseDao<T>(value){//        //业务处理//    }//};////class AndroidUserDao : public UserDao<int>{//public://    AndroidUserDao(int value) : UserDao<int>(value){////    }//};//6.函数指针作为函数参数传递#endif

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 __cplusplusextern "C" {#endif/* * Class:     com_tz_ndk_cpp_NDKCpp * Method:    callCppSuperClassPointer * Signature: ()V */JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppSuperClassPointer  (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppPureVirtualFunc        (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppFuncTemplate        (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppFuncTemplatePrinciple        (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppClassTemplate        (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppFuncPointerParam        (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif

com_tz_ndk_cpp_NDKCpp.cpp
#include <iostream>#include "com_tz_ndk_cpp_NDKCpp.h"using namespace std;//1.C++中:父类类型指针一些注意问题#import "Company.h"//1.1 回顾//void salary(Company &company){//    company.salary();//}JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppSuperClassPointer        (JNIEnv *, jobject){    //1.1 回顾//    AliCompany aliCompany;//    //需要申明为虚函数,才会调用子类方法//    //多态//    //虚函数://    //第一点:在类继承体系中存在//    //第二点:同时覆盖父类的方法//    //第三点:同时父类引用指向子类实例//    salary(aliCompany);    //1.2 分析对象的大小//    Company company;    //测试结果一:发现我们将方法申明为虚函数,对象的大小增大了,对象大小8    //测试结果二:我们在类中添加了两个虚函数包括一个属性,结果对象的大小是8    //总结分析: 添加了virtual关键字修饰函数,那么对象会多一个指针,这个指针指向一个虚函数表    //虚函数表:包括了当前类中的所有的虚函数//    __android_log_print(ANDROID_LOG_INFO,"main","company大小: %d", sizeof(company));    //1.3 分析对象数组存在的一些问题//    TzCompany tzCompany[] = {TzCompany("潭州教育",9),TzCompany("潭州软件",4),TzCompany("潭州语言",4)};////    //回顾:数组保存是首地址////    //子类////    TzCompany* tz_com_p = tzCompany;////    //通过指针位移方式遍历指针////    tz_com_p++;////    __android_log_print(ANDROID_LOG_INFO,"main","公司名称: %s",tz_com_p->name);////    //父类引用指向子类实例//    //效果演示:发现是乱码//    //分析问题:因为指针++核心本质=首地址+对象实际大小//    //company大小是8//    //tzCompany大小是12//    //例如://    //tzCompany = 假设首地址=0x0000002//    //tzCompany++ = 首地址++ = 0x0000014//    //company = 假设首地址=0x0000002//    //company++ = 首地址++ = 0x0000010//    //总结:如果一样大就能够找到,不一样就报错或者说乱码      //解决方案:循环遍历//    Company* com_p = tzCompany;//    com_p++;//    __android_log_print(ANDROID_LOG_INFO,"main","公司名称: %s",com_p->name);}//2.C++中:纯虚函数(抽象类)JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppPureVirtualFunc        (JNIEnv *, jobject){//    TzCompany company;//    company.salary();}//3.C++中:函数模版(类似于Java泛型)//3.1 普通的写法//int getMin(int a,int b){//   return a < b ? a : b;//}//char getMin(char a,char b){//    return a < b ? a : b;//}//double getMin(double a,double b){//    return a < b ? a : b;//}//3.2 函数模版//定义函数模版类型(申明一个函数模版)//template <typename T>//T getMin(T a,T b){//    return a < b ? a : b;//}//3.3 函数模版和函数重载同时存在//int getMin(int a,int b){//    __android_log_print(ANDROID_LOG_INFO,"main","调用了函数重载");//    return a < b ? a : b;//}//template <typename T>//T getMin(T a,T b){//    __android_log_print(ANDROID_LOG_INFO,"main","调用了模版函数");//    return a < b ? a : b;//}JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppFuncTemplate        (JNIEnv *, jobject){    //3.1 普通的写法//    getMin(10,20);//    getMin('A','B');//    getMin(10.545,20.343);    //3.2 函数模版//    int result = getMin(10,20);//    char result = getMin('A','B');//    float a = 10.5;//    float b = 20.6;//    float result = getMin(a,b);//    __android_log_print(ANDROID_LOG_INFO,"main","值:%lf",result);    //3.3 函数模版和函数重载同时存在    //调用了函数重载//    int a = 100;//    int b = 200;//    int result = getMin(a ,b);    //调用了模版方法//    char a = 'a';//    char b = 'b';//    char result = getMin(a ,b);    //总结:优先匹配普通方法,如果匹配不到,再去匹配函数模版}//4.C++中:函数模版机制(原理)//编译过程(4个步骤)//第一步:预处理文件(后缀名.i文件)//第二步:转成汇编文件(后缀名.s文件)//第三步:转成目标文件(后缀名.o文件)//第四步:链接生成目标文件(可执行文件)//template <typename T>//T getMin(T a,T b){//    __android_log_print(ANDROID_LOG_INFO,"main","调用了模版函数");//    return a < b ? a : b;//}//////添加方法是有编译器自动完成//int getMin(int a,int b){//    return a < b ? a : b;//}JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppFuncTemplatePrinciple        (JNIEnv *, jobject){//    int result = getMin(10,30);//    getMin(10,30);}//5.C++中:模版类JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppClassTemplate        (JNIEnv *, jobject){}//6.函数指针作为函数参数传递//int getMin(int a,int b){//    return a < b ? a : b;//}//6.1 函数指针(别名方式实现)//typedef int(*get_min_p)(int a,int b);////这个将函数指针的别名作为参数//void biz(get_min_p p,int a,int b){//    int result = p(a,b);//    __android_log_print(ANDROID_LOG_INFO,"main","值:%d",result);//}//6.2 直接使用//这个将函数指针直接作为参数//void biz2(int(*p)(int a,int b),int a,int b){//    int result = p(a,b);//    __android_log_print(ANDROID_LOG_INFO,"main","值:%d",result);//}//6.3 补充内容:函数指针结合函数模版(行不通)//template <typename T>//void getMin(int a,int b){//    //return a < b ? a : b;//}//typedef void(*get_min_p)(T a,T b);//void biz(get_min_p p,int a,int b){////}JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppFuncPointerParam        (JNIEnv *, jobject){    //6.1 函数指针(别名方式实现)//    get_min_p p = getMin;//    int result = p(10,20);//    __android_log_print(ANDROID_LOG_INFO,"main","值:%d",result);    //6.2 直接使用//    biz(getMin,10,20);//    biz2(getMin,10,20);    //6.3 补充内容}




整理自示例代码




0 0