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_HFriendClass.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_HFriendFunc.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_HObjectSize.cpp
#include "ObjectSize.h"#include <android/log.h>void ObjectSizeC::toString() { __android_log_print(ANDROID_LOG_INFO,"main","调用了");}
#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_HStaticClass.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_HTeacher.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
- NDK-CPP语言-构造函数+New和Delete和Static关键字+对象大小
- new/delete 和 复制构造函数
- 构造函数delete和default关键字分析
- new关键字和delete关键字
- static new delete关键字
- C++-关键字new和delete
- 黑马程序员--面向对象之一:面向对象概念、类和对象的关系、封装、构造函数、this关键字、static关键字
- Java new一个子类对象时static和构造函数的执行顺序
- Cpp--new和delete的应用
- Cpp--重载全局的new和delete
- C++笔记 构造函数属性初始化,new,delete,对象的大小
- 关键字的简单总结:static、const、sizeof以及malloc和new、delete和free
- 构造器和new关键字
- static 变量和static 构造函数 以及对象初始化顺序
- 用构造方法构建对象时使用new关键字和不使用new关键字的差别
- java基础第三天 构造函数和static关键字
- 习题(练习类、构造函数和static关键字)
- Java static关键字和构造函数执行顺序
- 集成Dubbo服务(Spring)
- 软通动力,工资到底是多少呢?
- logback 常用配置详解(二) <appender>
- BZOJ 1012: [JSOI2008]最大数maxnumber
- [ATF]ARMv8 psci bootup target cpu api
- NDK-CPP语言-构造函数+New和Delete和Static关键字+对象大小
- Python+Django开发游戏充值管理后台
- Android下Activity结束(finish())之后没有释放内存问题的解决方法
- Android图片压缩(质量压缩和尺寸压缩)
- POI2014Bricks
- LeetCode112. Path Sum
- github将一个远程仓库的某个分支放到一个新的仓库中(提交历史纪录也导过去)
- 2.IntentFilter的匹配规则
- 【NOI2016】网格,离散化+求割点