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="指针和引用区别"
        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","不成立");
    }

}


整理自示例代码






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值