布局文件:
<?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="指针和引用区别"
android:textSize="18sp"
android:onClick="clickCppPointerAndRefDiff"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="运算符重载: 属性修饰符为public"
android:textSize="18sp"
android:onClick="clickCppOperatorPublic"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="运算符重载: 属性修饰符为private"
android:onClick="clickCppOperatorPrivate"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="运算符重载: 一元运算符"
android:textSize="18sp"
android:onClick="clickCppOperatorUnitary"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="运算符重载: 输出函数"
android:textSize="18sp"
android:onClick="clickCppOperatorOut"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="运算符重载:重载'='号"
android:textSize="18sp"
android:onClick="clickCppOperatorWait"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="运算符重载:重载'()'号"
android:textSize="18sp"
android:onClick="clickCppOperatorBrackets"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="运算符重载:重载'!='号"
android:textSize="18sp"
android:onClick="clickCppOperatorNotEqualTo"/>
</LinearLayout>
MainActivity:
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();
String str1 = "Str1";
String str2 = "Str2";
String str3 = str1 + str2;
if(str1.equals(str2)){
}
}
public void clickCppOperatorPublic(View v){
ndkCpp.callCppOperatorPublic();
}
public void clickCppOperatorPrivate(View v){
ndkCpp.callCppOperatorPrivate();
}
public void clickCppOperatorUnitary(View v){
ndkCpp.callCppOperatorUnitary();
}
public void clickCppOperatorOut(View v){
ndkCpp.callCppOperatorOut();
}
public void clickCppPointerAndRefDiff(View v){
ndkCpp.callCppPointerAndRefDiff();
}
public void clickCppOperatorWait(View v){
ndkCpp.callCppOperatorWait();
}
public void clickCppOperatorBrackets(View v){
ndkCpp.callCppOperatorBrackets();
}
public void clickCppOperatorNotEqualTo(View v){
ndkCpp.callCppOperatorNotEqualTo();
}
}
public class NDKCpp {
//1.指针和引用区别
public native void callCppPointerAndRefDiff();
//2.运算符重载: "+"or"-"(属性修饰符为public)
public native void callCppOperatorPublic();
//3.运算符重载: "+"or"-"(属性修饰符为private)
public native void callCppOperatorPrivate();
//4.运算符重载: 一元运算符
public native void callCppOperatorUnitary();
//5.运算符重载: 输出函数
public native void callCppOperatorOut();
//6.运算符重载:重载'='号
public native void callCppOperatorWait();
//7.运算符重载:重载'()'号
public native void callCppOperatorBrackets();
//8.操作符重载:重载'!='号
public native void callCppOperatorNotEqualTo();
}
c代码:
Product.h
#ifndef DREAM_NDK_CPP_11_7_17_PRODUCT_H
#define DREAM_NDK_CPP_11_7_17_PRODUCT_H
#include <iostream>
#include <android/log.h>
using namespace std;
class Product {
//2.运算符重载: "+"or"-"(属性修饰符为public)
public:
int count;
public:
Product(int count);
Product& operator+(Product &product);
Product& operator-(Product &product);
Product& operator*(Product &product);
Product& operator/(Product &product);
//3.运算符重载: "+"or"-"(属性修饰符为private)
//友元函数解决
private:
int price;
public:
//定义友元函数
friend Product& operator+(Product &product1,Product &product2);
Product();
//4.运算符重载: 一元运算符(++或者--)
public:
//前置++(例如:++a)
Product& operator++();
//后置++(例如:a++)
//注意:编译器为了区分方法的重载,所以在后置++运算符重载方法中,添加了参数列表
//目的:为了区分到底是前置++还是后置++
Product& operator++(int);
//前置--
Product& operator--();
//后置--
Product& operator--(int);
//5.运算符重载: 输出函数
//ostream:输出函数
public:
//打印单个
// friend void operator<<(ostream &out,Product &product);
//打印多个
friend ostream& operator<<(ostream &out,Product &product);
//6.运算符重载:重载'='号
private:
char *name;
public:
//构造函数
Product(char* name);
//析构函数
~Product(){
//指针需要判断空NULL
if (this->name != NULL){
//释放内存
free(this->name);
this->name = NULL;
}
}
//拷贝函数
Product(const Product &product){
//我们希望深拷贝
int len = sizeof(product.name) + 1;
this->name = (char*)malloc(len);
strcpy(this->name,product.name);
}
//实现'='运算符
Product& operator=(Product &product){
//先释放内存,再重新开辟新的内存区域
if(this->name != NULL){
//释放内存
free(this->name);
this->name = NULL;
}
//重新赋值
int len = sizeof(product.name) + 1;
this->name = (char*)malloc(len);
strcpy(this->name,product.name);
return *this;
}
char* getName();
void print_name();
//7.运算符重载:重载'()'号
int operator()(int ct,int pri){
return ct * pri;
}
//8.操作符重载:重载'!='号(条件运算符)
public:
Product(char* name,int price){
this->name = name;
this->price = price;
}
//说明:再C++中0代表是false 1代表是true
int operator==(Product &product){
//判断字符串是否相等
int result = strcmp(this->name,product.name);
if(result != 0){
return 0;
}
if(this->price != product.price){
return 0;
}
return 1;
}
//重载'!='条件运算符
int operator!=(Product &product){
int result = strcmp(this->name,product.name);
if(result != 0){
return 1;
}
if(this->price != product.price){
return 1;
}
return 0;
}
//重载'<='条件运算符
int operator<=(Product &product){
int result = strcmp(this->name,product.name);
if(result >= 0){
return 0;
}
if(this->price >= product.price){
return 0;
}
return 1;
}
};
#endif
Product.cpp
#include "Product.h"
//2.运算符重载: "+"or"-"(属性修饰符为public)
Product::Product(int count) {
this->count = count;
}
Product& Product::operator+(Product &product) {
int count = this->count + product.count;
Product pro = Product(count);
return pro;
}
Product& Product::operator-(Product &product) {
int count = this->count - product.count;
Product pro = Product(count);
return pro;
}
Product& Product::operator*(Product &product) {
int count = this->count * product.count;
Product pro = Product(count);
return pro;
}
Product& Product::operator/(Product &product) {
int count = this->count / product.count;
Product pro = Product(count);
return pro;
}
Product::Product() {
}
//4.运算符重载: 一元运算符(++或者--)
//前置++
Product& Product::operator++() {
this->count = this->count + 1;
return *this;
}
//后置++
Product& Product::operator++(int) {
//注意:后置++是先返回,再相加
//保存原始数据(拷贝一份)
Product product = *this;
this->count = this->count + 1;
return product;
}
//前置--
Product& Product::operator--() {
this->count = this->count - 1;
return *this;
}
//后置--
Product& Product::operator--(int) {
//注意:后置--是先返回,再相减
//保存原始数据(拷贝一份)
Product product = *this;
this->count = this->count - 1;
return product;
}
//5.运算符重载: 输出函数
Product::Product(char* name){
//重新开辟新的内存区域(堆内存)
//+1:目的为了告诉程序结束符号('\0')
int len = sizeof(name) + 1;
this->name = (char*)malloc(len);
strcpy(this->name,name);
}
char* Product::getName() {
return this->name;
}
void Product::print_name() {
__android_log_print(ANDROID_LOG_INFO,"main","name值: %s",this->name);
}
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
#include <android/log.h>
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppPointerAndRefDiff
(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorPublic
(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorPrivate
(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorUnitary
(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorOut
(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorWait
(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorBrackets
(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorNotEqualTo
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
com_tz_ndk_cpp_NDKCpp.cpp
#include <iostream>
#include "com_tz_ndk_cpp_NDKCpp.h"
#include "bean/Product.h"
using namespace std;
//1.指针和引用区别(什么时候使用指针?什么时候使用引用?)
//相同点
//都是地址概念,指针指向的是一块内存区域,他的内容是所指向内存的地址,引用某块内存的别名
//通俗:都是代表地址
//不同点
//第一点:指针是内存地址,引用是内存地址别名,并且程序需要为指针变量分配内存区域,而引用不需要分配内存区域
//第二点:引用在使用的时候不需要*解引用,但是指针需要*解引用
//第三点:引用只能被初始化一次,之后不能够改变,但是指针可以
//第四点:引用不能够为NULL,但是指针可以为NULL
//第五点:sizeof(引用)得到的是引用所指向的变量的大小,sizeof(指针)得到的是指针本身的大小
//第六点:指针(++或者--)代表是地址位移,但是引用(++或者--)实际上引用对应的值改变
//场景
void print_int(const int &b){
__android_log_print(ANDROID_LOG_INFO,"main","直接使用:%d",b);
}
void print_int(const int *p){
//指针在使用的时候必须判断NULL(释放内存)
if (p != NULL){
__android_log_print(ANDROID_LOG_INFO,"main","直接使用:%d",*p);
}
}
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppPointerAndRefDiff
(JNIEnv *env, jobject jobj){
//第一点:指针是内存地址,引用是内存地址别名,并且程序需要为指针变量分配内存区域,而引用不需要分配内存区域
// int a = 100;
// int &b = a;
// int *p = &a;
// __android_log_print(ANDROID_LOG_INFO,"main","引用b地址: %p",&b);
// __android_log_print(ANDROID_LOG_INFO,"main","变量a地址: %p",&a);
//
// __android_log_print(ANDROID_LOG_INFO,"main","指针p地址: %p",&p);
//第二点:引用再使用的时候不需要*解引用,但是指针需要*解引用
// int a = 100;
// int &b = a;
// int *p = &a;
// //打印a的值:使用上就不一样了
// __android_log_print(ANDROID_LOG_INFO,"main","引用b地址: %d",b);
// __android_log_print(ANDROID_LOG_INFO,"main","引用b地址: %d",*p);
//第三点:引用只能被初始化一次,之后不能够改变,但是指针可以
// int a = 100;
// int b = 200;
// int &c = a;
// int *p = &a;
// //引用不能够再次赋值(会出错)
&c = b;
// //指针可以
// p = &b;
//第四点:引用不能够为NULL,但是指针可以为NULL
// int a = 100;
// int &b = a;
// int *p = &a;
// //不能够为空
&b = NULL;
// //指针可以
// p = NULL;
//第五点:sizeof(引用)得到的是引用所指向的变量的大小,sizeof(指针)得到的是指针本身的大小
// double a = 100;
// double &b = a;
// double *p = &a;
// //指针本身是一个地址,地址本身是一个int类型
// //sizeof(引用)大小由类型决定,但是指针固定就是4
// __android_log_print(ANDROID_LOG_INFO,"main","sizeof(引用): %d", sizeof(b));
// __android_log_print(ANDROID_LOG_INFO,"main","sizeof(指针): %d", sizeof(p));
//第六点:指针(++或者--)代表是地址位移,但是引用(++或者--)实际上引用对应的值改变
// int a = 100;
// int &b = a;
// int *p = &a;
// b++;
// p++;
// __android_log_print(ANDROID_LOG_INFO,"main","b的值: %d", b);
// __android_log_print(ANDROID_LOG_INFO,"main","p的值: %d", *p);
//模拟一个场景
}
//2.运算符重载: "+"or"-"(属性修饰符为public)
//Product& add(Product &product1,Product &product2){
// int count = product1.count + product2.count;
// Product product = Product(count);
// return product;
//}
//operator:重载运算符关键字
//+:代表你需要重载哪一个运算符
//Product& operator+(Product &product1,Product &product2){
// int count = product1.count + product2.count;
// Product product = Product(count);
// return product;
//}
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorPublic
(JNIEnv *, jobject){
// Product product1 = 100;
// Product product2 = 200;
// add(product1,product2);
// Product product3 = product1 + product2;
// __android_log_print(ANDROID_LOG_INFO,"main","值: %d", product3.count);
}
//3.运算符重载: "+"or"-"(属性修饰符为private)
//解决方案一:成员函数
//解决方案而:友元函数
//在外部通过友元函数访问类的私有属性
//Product& operator+(Product &product1,Product &product2){
// int price = product1.price + product2.price;
// Product product;
// product.price = price;
// return product;
//}
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorPrivate
(JNIEnv *, jobject){
__android_log_print(ANDROID_LOG_INFO,"main","运算符重载:属性修饰符为private");
}
//4.运算符重载: 一元运算符(++或者--)
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorUnitary
(JNIEnv *, jobject){
// Product product;
// product.count = 100;
--product;
//
// Product product1 = product++;
// __android_log_print(ANDROID_LOG_INFO,"main","product值:%d",product.count);
// __android_log_print(ANDROID_LOG_INFO,"main","product1值:%d",product1.count);
// char a = 'A';
// ++a;
// __android_log_print(ANDROID_LOG_INFO,"main","a的值:%c",a);
}
//5.运算符重载: 输出函数
//作业:自己新建VS项目,测试运行
ostream& operator<<(ostream &out, Product &product) {
out << "count值:" << product.count << endl;
return out;
}
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorOut
(JNIEnv *, jobject){
//输出基本数据类型
cout << "Dream" << endl;
//问题:你能够访问其他类的属性吗?
//ostream属于iostream中的属性
//解决方案:友元函数
//这个也就是友元函数真正的存在的意义
//友元函数的真正作用:当我们无法给已存在类添加成员函数的时候,可以采用友元函数解决
Product product = Product(100);
cout << product;
//问题:连续打印
//解决方案:返回值解决(返回ostream&)
cout << product << product << product;
}
//6.运算符重载:重载'='号
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorWait
(JNIEnv *, jobject){
//拷贝一个新的对象
// Product product = 100;
// Product product1 = product;
//赋值运算(浅拷贝值)
Product product1 = "Dream";
Product product2 = "Hello";
product2 = product1;
//需求:已经创建了我希望重载'='是深拷贝
// product2.print_name();
char *name1 = product1.getName();
char *name2 = product2.getName();
__android_log_print(ANDROID_LOG_INFO,"main","product1.name值:%d",*name1);
__android_log_print(ANDROID_LOG_INFO,"main","product2.name值:%d",*name2);
__android_log_print(ANDROID_LOG_INFO,"main","product1.name地址:%p",name1);
__android_log_print(ANDROID_LOG_INFO,"main","product2.name地址:%p",name2);
}
//7.运算符重载:重载'()'号
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorBrackets
(JNIEnv *, jobject){
Product product = Product(10);
//需求:传入商品的价格和数量,返回总价
//解决方案:可以通过重载'()'运算符实现
int sum_price = product(2,100);
__android_log_print(ANDROID_LOG_INFO,"main","总价格: %d",sum_price);
}
//8.操作符重载:重载'!='、'=='、'>='号(条件运算符)
JNIEXPORT void JNICALL Java_com_tz_ndk_cpp_NDKCpp_callCppOperatorNotEqualTo
(JNIEnv *, jobject){
// Product product1 = Product("Mac book pro 2016顶配",20000);
// Product product2 = Product("Mac book pro 2016顶配",20000);
// Product product2 = Product("Surface book 2016顶配",22000);
//默认报错
// if(product1 == product2){
//
// }
//重载运算符
// if(product1 == product2){
// __android_log_print(ANDROID_LOG_INFO,"main","相等");
// }else{
// __android_log_print(ANDROID_LOG_INFO,"main","不相等");
// }
// if(product1 != product2){
// __android_log_print(ANDROID_LOG_INFO,"main","不相等");
// }else{
// __android_log_print(ANDROID_LOG_INFO,"main","相等");
// }
Product product1 = Product("C",100);
Product product2 = Product("B",100);
if(product1 <= product2){
__android_log_print(ANDROID_LOG_INFO,"main","成立");
}else{
__android_log_print(ANDROID_LOG_INFO,"main","不成立");
}
}
整理自示例代码