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

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="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 __cplusplus
extern "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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值