NDK-CPP语言-构造函数+New和Delete和Static关键字+对象大小

来源:互联网 发布:mac 双系统 win7 驱动 编辑:程序博客网 时间:2024/06/06 06:38
public class NDKCpp {    //1.C++中构造函数    public native void callCppConstruct();    //2.C++中new关键字、delete关键字    public native void callCppNewOrDelete();    //3.C++中static关键字    public native void callCppStatic();    //4.C++中对象的大小    public native void callCppObjectSize();    //5.C++中const修饰函数(常量属性、常量函数)    public native void callCppConstFunc();    //6.C++中友元函数    public native void callCppFriendFunc();    //7.C++中友元类    public native void callCppFriendClass();}

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:    callCppConstruct * Signature: ()V */JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppConstruct        (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppNewOrDelete        (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppStatic        (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppObjectSize        (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppConstFunc        (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppFriendFunc        (JNIEnv *, jobject);JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppFriendClass        (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif

com_tz_ndk_cpp_NDKCpp.cpp

#include <iostream>#include "com_tz_ndk_cpp_NDKCpp.h"#include "bean/Student.h"#include "bean/StaticClass.h"using namespace std;//1.C++中构造函数//问题一://需求:Teacher类中没有提供无参数构造函数,在Student类中定义一个Teacher属性变量?//发现问题:会报错(没有初始化)//解决方案:初始化//问题二:什么时候析构函数调用?JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppConstruct    (JNIEnv *env, jobject jobj){    //创建    //首先创建两个Teacher对象    //接下来创建一个Student对象    //Student student = Student("陈国军","Grace","Dream");    //释放    //首先析构Student    //写下来析构Teacher    //注意:顺序类似于(栈数据结构: 先进后出,后进先出)    //这个也是C++中对对象内存进行的管理机制(管理规则)}//2.C++中new关键字、delete关键字JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppNewOrDelete        (JNIEnv *, jobject){    //2.1 基本数据类型    //C语言中    //在我们堆内存开辟一块内存为int空间//    int *p = (int*)malloc(sizeof(int));//    *p = 100;//    //释放内存//    free(p);//    p = NULL;//    char *cp = (char*)malloc(sizeof(char));//    *cp = 'a';//    //释放内存//    free(cp);//    cp = NULL;    //C++中提供非常简便方式(采用new、delete关键字)    //new int相当于(int*)malloc(sizeof(int))//    int *p = new int;//    *p = 100;//    //释放内存////    delete p;////    free(p);    //2.2 数组类型    //在C语言中(动态内存分配)    //返回的p就是数组的首地址,通过指针位移方式一个个读取//    int *p = (int*)malloc(sizeof(int)*10);//    p[0] = 100;//    free(p);    //C++中//    int *p = new int[10];//    p[0] = 100;//    //注意:释放数组//    delete[] p;    //2.3 分配对象    //一下写法是允许的,C++中支持C的混合编程//    Teacher* teacher = (Teacher*)malloc(sizeof(Teacher));//    teacher->setName("Dream");//    //释放内存//    free(teacher);    //直接C++中语法    //这个开辟内存栈内存(自动管理)//    Teacher teacher1 = Teacher();    //开辟的是堆内存//    Teacher* teacher = new Teacher();//    teacher->setName("Dream");//    delete teacher;}//3.C++中static关键字//3.1 static修饰属性//3.2 static修饰函数//可以这样写//注意:需要在函数的外部进行初始化int StaticClass::sex = 100;JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppStatic        (JNIEnv *env, jobject jobj){//    StaticClass staticClass = StaticClass("Dream");//    staticClass.sex = 100;//    __android_log_print(ANDROID_LOG_INFO,"main","sex值: %d",StaticClass::sex);    //访问静态方法(必须指定类名)    StaticClass::toString();}//4.C++中对象的大小//回想:结构体大小//根据结果:ObjectSizeA、ObjectSizeB、ObjectSizeC大小分别是8、12、12//内存分配//C++中类对象的属性和成员函数内存分开存储的//普通属性:存储在对象中,与结构体存储规则一样//静态属性:存在在静态数据区中,(内存区:栈、堆、静态区、全局区、代码区)//成员函数:存储在代码区//问题:既然成员函数都是放置在代码区,共享,那么函数怎么知道当前访问的是哪一个对象?//解决方案:this区分#include "bean/ObjectSize.h"JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppObjectSize        (JNIEnv *env, jobject jobj){    __android_log_print(ANDROID_LOG_INFO,"main","ObjectSizeA大小: %d", sizeof(ObjectSizeA));    __android_log_print(ANDROID_LOG_INFO,"main","ObjectSizeB大小: %d", sizeof(ObjectSizeB));    __android_log_print(ANDROID_LOG_INFO,"main","ObjectSizeC大小: %d", sizeof(ObjectSizeC));    //C++中类的底层实现相当于就是一个结构体    ObjectSizeC c1;    ObjectSizeC c2;    ObjectSizeC c3;    c1.toString();    c2.toString();    c3.toString();}//5.C++中const修饰函数(常量属性、常量函数)//const修饰什么?//属性不能够修改//总结:const修饰的this指针所指向的内存区域不能够修改JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppConstFunc        (JNIEnv *env, jobject jobj){    __android_log_print(ANDROID_LOG_INFO,"main","C++中const修饰函数(常量属性、常量函数)");}//6.C++中友元函数//需求:我要访问私有属性#include "bean/FriendFunc.h"//友元函数实现void update_name(FriendFunc *func,char *name){    func->name = name;}JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppFriendFunc        (JNIEnv *, jobject){    FriendFunc* friendFunc = new FriendFunc();    update_name(friendFunc,"Hello");    __android_log_print(ANDROID_LOG_INFO,"main","值: %s",friendFunc->getName());    //硬是要访问?    //解决方案:友元函数}//7.C++中友元类//需求:A类访问B类中的私有属性或者函数?//解决方案:友元类(说白了就是Java反射机制的底层实现)//注意:A类需要申明B类是我的友元类,之后B类就能够访问A类中的任何属性和方法#include "bean/FriendClass.h"JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppFriendClass        (JNIEnv *env, jobject jobj){    //打印结果:    //FriendClassA:创建了2次,拷贝了1次,析构了3次    //FriendClassB:创建了1次,析构了1次    //分析:为什么不能够修改?    //第一次创建:FriendClassA构造函数//    FriendClassA friendClassA = FriendClassA();//    friendClassA.setName("Dream");////    __android_log_print(ANDROID_LOG_INFO,"main","修改之前:%s",friendClassA.getName());////    //第二次创建:就是因为FriendClassB有一个FriendClassA属性调用构造函数(因为对象属性需要初始化)//    FriendClassB friendClassB;//    //拷贝对象:实参初始化行参,这个时候也会进行场景对象拷贝//    //第一次析构(第一次析构是行参):因为行参在update_friendClassA方法中使用完毕,那么立马析构行参对象//    friendClassB.update_friendClassA(friendClassA,"Jack");////    __android_log_print(ANDROID_LOG_INFO,"main","修改之后:%s",friendClassA.getName());    //纠正    //第二次析构:析构friendClassA    //第三次析构:析构friendClassB中的friendClassA属性    //怎么才能够实现修改?    //解决方案    //解决方案一:传递指针//    FriendClassA* friendClassA = new FriendClassA();//    friendClassA->setName("Dream");////    __android_log_print(ANDROID_LOG_INFO,"main","修改之前:%s",friendClassA->getName());////    FriendClassB friendClassB;//    friendClassB.update(friendClassA,"Jack");//    __android_log_print(ANDROID_LOG_INFO,"main","修改之后:%s",friendClassA->getName());    //解决方案二:传递指针的引用    FriendClassA friendClassA = FriendClassA();    friendClassA.setName("Dream");    __android_log_print(ANDROID_LOG_INFO,"main","修改之前:%s",friendClassA.getName());    FriendClassB friendClassB;    friendClassB.update_p(friendClassA,"Jack");    __android_log_print(ANDROID_LOG_INFO,"main","修改之后:%s",friendClassA.getName());}


ConstFunc.h

#ifndef DREAM_NDK_CPP_11_5_16_CONSTFUNC_H#define DREAM_NDK_CPP_11_5_16_CONSTFUNC_Hclass ConstFunc {private:    int age;    char* name;public:    void toString() const {        //不允许修改//        age = 100;//        name = 100;//        this = (ConstFunc*)0x1211323;    }};#endif //DREAM_NDK_CPP_11_5_16_CONSTFUNC_H

FriendClass.h

#ifndef DREAM_NDK_CPP_11_5_16_FRIENDCLASS_H#define DREAM_NDK_CPP_11_5_16_FRIENDCLASS_Hclass FriendClassA {private:    int age;    char* name;    void toString();    //声明FriendClassB是FriendClassA的朋友    friend class FriendClassB;public:    FriendClassA();    ~FriendClassA();    FriendClassA(const FriendClassA &friendClassA);    void setName(char* name);    char* getName();};class FriendClassB {private:    FriendClassA friendClassA;public:    FriendClassB();    ~FriendClassB();    FriendClassB(const FriendClassB &friendClassB);    void myprint();    void update_friendClassA(FriendClassA friendClassA,char* name);    //传递指针    void update(FriendClassA* friendClassA,char* name);    //传递指针的引用    void update_p(FriendClassA &friendClassA,char* name);};#endif //DREAM_NDK_CPP_11_5_16_FRIENDCLASS_H
FriendClass.cpp

#include "FriendClass.h"#include <android/log.h>FriendClassA::FriendClassA() {    __android_log_print(ANDROID_LOG_INFO,"main","FriendClassA构造函数");}FriendClassA::~FriendClassA() {    __android_log_print(ANDROID_LOG_INFO,"main","FriendClassA析构函数");}FriendClassA::FriendClassA(const FriendClassA &friendClassA) {    this->age = friendClassA.age;    this->name = friendClassA.name;    __android_log_print(ANDROID_LOG_INFO,"main","FriendClassA拷贝函数");}void FriendClassA::toString() {}void FriendClassA::setName(char *name) {    this->name = name;}char* FriendClassA::getName() {    return this->name;}/************下面是B类**********/FriendClassB::FriendClassB() {    __android_log_print(ANDROID_LOG_INFO,"main","FriendClassB构造函数");}FriendClassB::~FriendClassB() {    __android_log_print(ANDROID_LOG_INFO,"main","FriendClassB析构函数");}FriendClassB::FriendClassB(const FriendClassB &friendClassB) {    __android_log_print(ANDROID_LOG_INFO,"main","FriendClassB拷贝函数");}void FriendClassB::update_friendClassA(FriendClassA friendClassA,char* name) {    friendClassA.name = name;}void FriendClassB::update(FriendClassA* friendClassA, char *name) {    friendClassA->name = name;}void FriendClassB::update_p(FriendClassA &friendClassA, char *name) {    friendClassA.name = name;}void FriendClassB::myprint() {    friendClassA.age;    friendClassA.toString();}

FriendFunc.h

#ifndef DREAM_NDK_CPP_11_5_16_FRIENDFUNC_H#define DREAM_NDK_CPP_11_5_16_FRIENDFUNC_Hclass FriendFunc {private:    char* name;public:    FriendFunc();    //声明一个友元函数(friend关键字)    friend void update_name(FriendFunc *func,char *name);    char* getName();};#endif //DREAM_NDK_CPP_11_5_16_FRIENDFUNC_H
FriendFunc.cpp

#include "FriendFunc.h"FriendFunc::FriendFunc() {    this->name = "Dream";}char* FriendFunc::getName() {    return this->name;}

ObjectSize.h

#ifndef DREAM_NDK_CPP_11_5_16_OBJECTSIZE_H#define DREAM_NDK_CPP_11_5_16_OBJECTSIZE_Hclass ObjectSizeA {private:    int a;    int b;};class ObjectSizeB {private:    int a;    int b;    int c;public:    static int d;};class ObjectSizeC {private:    int a;    int b;    int c;public:    void toString();};#endif //DREAM_NDK_CPP_11_5_16_OBJECTSIZE_H
ObjectSize.cpp

#include "ObjectSize.h"#include <android/log.h>void ObjectSizeC::toString() {    __android_log_print(ANDROID_LOG_INFO,"main","调用了");}


StaticClass.h

#ifndef DREAM_NDK_CPP_11_5_16_STATICCLASS_H#define DREAM_NDK_CPP_11_5_16_STATICCLASS_H#include <android/log.h>class StaticClass {private:    char* name;public:    static int sex;    StaticClass(char* name);    ~StaticClass();    static void toString(){        __android_log_print(ANDROID_LOG_INFO,"main","sex:%d",sex);    }};#endif //DREAM_NDK_CPP_11_5_16_STATICCLASS_H
StaticClass.cpp

#include "StaticClass.h"#include <android/log.h>StaticClass::StaticClass(char *name) {    this->name = name;    __android_log_print(ANDROID_LOG_INFO,"main","构造函数");}StaticClass::~StaticClass() {    __android_log_print(ANDROID_LOG_INFO,"main","析构函数");}
Student.h

#ifndef DREAM_NDK_CPP_11_5_16_STUDENT_H#define DREAM_NDK_CPP_11_5_16_STUDENT_H#include "Teacher.h"#include <android/log.h>//解决方案:初始化//第一种写法//在Teacher类中提供无参数构造方法//第二种写法//class Student {//private://    char* name;//    //班主任老师//    Teacher headTeacher = "Dream";//    //科目老师//    Teacher subjectTeacher = "Dream";//public://    Student(char* name);//};//第三种写法//class Student {//private://    char* name;//    //班主任老师//    Teacher headTeacher = Teacher("Grace");//    //科目老师//    Teacher subjectTeacher = Teacher("Dream");//public://    Student(char* name);//};//第四种写法//class Student {//private://    char* name;//    //班主任老师//    Teacher headTeacher;//    //科目老师//    Teacher subjectTeacher;//public://    Student::Student(char *name):headTeacher("Grace"),subjectTeacher("Dream") {//        this->name = name;//    }//};//第五种写法//class Student {//private://    char* name;//    //班主任老师//    Teacher headTeacher;//    //科目老师//    Teacher subjectTeacher;//public://    Student(char *name,char* headName,char* subjectName)//            :headTeacher(headName),subjectTeacher(subjectName) {//        this->name = name;//        __android_log_print(ANDROID_LOG_INFO,"main","Student构造函数");//    }////    ~Student(){//        __android_log_print(ANDROID_LOG_INFO,"main","Student析构函数");//    }////};#endif //DREAM_NDK_CPP_11_5_16_STUDENT_H

Teacher.h

#ifndef DREAM_NDK_CPP_11_5_16_TEACHER_H#define DREAM_NDK_CPP_11_5_16_TEACHER_H#include <android/log.h>class Teacher {private:    char *name;public:    Teacher();    Teacher(char* name);    ~Teacher();    void setName(char* name);};#endif //DREAM_NDK_CPP_11_5_16_TEACHER_H
Teacher.cpp

#include "Teacher.h"Teacher::Teacher() {    this->name = "Dream";    __android_log_print(ANDROID_LOG_INFO,"main","Teacher构造函数");}Teacher::Teacher(char *name) {    this->name = name;    __android_log_print(ANDROID_LOG_INFO,"main","Teacher构造函数");}Teacher::~Teacher() {    __android_log_print(ANDROID_LOG_INFO,"main","Teacher析构函数");}void Teacher::setName(char *name) {    this->name = name;}

MainActivity.java


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();        //java中访问私有属性?  直接访问?        try {            //属于间接访问            Class<?> clazz = Class.forName("com.tz.ndk.cpp.MainActivity");            clazz.getField("ndkCpp");        } catch (Exception e) {            e.printStackTrace();        }        //反射机制访问私有属性    }    public void clickCppConstruct(View v){        ndkCpp.callCppConstruct();    }    public void clickCppNewOrDelete(View v){        ndkCpp.callCppNewOrDelete();    }    public void clickCppStatic(View v){        ndkCpp.callCppStatic();    }    public void clickCppObjectSize(View v){        ndkCpp.callCppObjectSize();    }    public void clickCppConstFunc(View v){        ndkCpp.callCppConstFunc();    }    public void clickCppFriendFunc(View v){        ndkCpp.callCppFriendFunc();    }    public void clickCppFriendClass(View v){        ndkCpp.callCppFriendClass();    }}

配置文件CMakeLists.txt:


# Sets the minimum version of CMake required to build the native# library. You should either keep the default value or only pass a# value of 3.4.0 or lower.cmake_minimum_required(VERSION 3.4.1)# Creates and names a library, sets it as either STATIC# or SHARED, and provides the relative paths to its source code.# You can define multiple libraries, and CMake builds it for you.# Gradle automatically packages shared libraries with your APK.add_library( # Sets the name of the library.             native-lib             # Sets the library as a shared library.             SHARED             # Provides a relative path to your source file(s).             # Associated headers in the same location as their source             # file are automatically included.             src/main/cpp/com_tz_ndk_cpp_NDKCpp.cpp             src/main/cpp/bean/Student.cpp             src/main/cpp/bean/Teacher.cpp             src/main/cpp/bean/StaticClass.cpp             src/main/cpp/bean/ObjectSize.cpp             src/main/cpp/bean/ConstFunc.cpp             src/main/cpp/bean/FriendFunc.cpp             src/main/cpp/bean/FriendClass.cpp             )# Searches for a specified prebuilt library and stores the path as a# variable. Because system libraries are included in the search path by# default, you only need to specify the name of the public NDK library# you want to add. CMake verifies that the library exists before# completing its build.find_library( # Sets the name of the path variable.              log-lib              # Specifies the name of the NDK library that              # you want CMake to locate.              log )# Specifies libraries CMake should link to your target library. You# can link multiple libraries, such as libraries you define in the# build script, prebuilt third-party libraries, or system libraries.target_link_libraries( # Specifies the target library.                       native-lib                       # Links the target library to the log library                       # included in the NDK.                       ${log-lib} )




整理自示例代码









0 0
原创粉丝点击