4. OOP: Operator Overloading

Operator Overloading

0. Overview

We have some clue of package < iostream> now. However, for now, we could only do the operator based on default data type, such as int, char. What if we want to do operator on the user-defined class? We need to do operator overloading.

This time, we will overloading the operator+, operator*, operator++, operator[], operator<<, operator>>.

1. User-defined Class

Before overloading, let’s define a class for those operator.

// console cin, cout
#include<iostream>  
// file in, out
#include<fstream>
using namespace std;

class ThreeD{
public:
    int ht;
    int wid;
    int dep;

    // default constructor
    ThreeD() {
        ht = wid = dep = 0;
    }

    // know knid of constructor
    ThreeD(int i, int j, int k): ht(i), wid(j), dep(k) {}
    int getVol(){ return ht * wid * dep; }

    // overload operator
    ThreeD operator+(ThreeD t);
    ThreeD operator*(ThreeD t);
    ThreeD operator++();                // prefix
    ThreeD operator++(int neverUsed);   // postfix
    int & operator[](int k);

    //friend: allow function to access private paramenter
    friend ostream& operator<<(ostream& str, const ThreeD t);
	friend istream& operator>>(istream& str, ThreeD& t);
};

2. Operator+, Operator*

ThreeD ThreeD::operator+(ThreeD t){
    ThreeD temp;
    temp.ht = ht;
    temp.wid = t.wid;
    temp.dep = dep + t.dep;
    return temp;
}

ThreeD ThreeD::operator*(ThreeD t){
    ThreeD temp;
    temp.ht = ht * t.ht;
    temp.wid = wid * t.wid;
    temp.dep = dep * t.dep;
    return temp;
}

2. Operator++: prefix and postfix

For operator++, we have two types of that: prefix operator++ and postfix operator++. The way complier to distinguish these two operator++ is whether the function take the parameter.

// prefix
// complier knows that the operator without argument is prefix
ThreeD ThreeD::operator++(){
    ++ht;
    ++wid;
    ++dep;
    // this is a pointer pointing to the current object
    return *this;
}

// postfix
// complier knows that the operator with argument is postfix
// store the value first,which will be return at the end
// then, apply the increment.
ThreeD ThreeD::operator++(int neverUsed){
    ThreeD tmp = *this;
    ht++;
    wid++;
    dep++;
    return tmp;
}

3. Operator[]: return by reference

Similar to array, operator[] is to return the result by index/reference.

// if defined in this way, it's read-only
// const int & ThreeD::operator[](int k)

    //The origianl object will be returned to the calling function.
	//No extra copying effort is needed.  It is faster than return by value,
	//which requires an extra copy to be created and returned to the calling function.
	//Because an object is returned, rather than a value, the function can appear
	//on the left side of an statement.
int & ThreeD::operator[](int k){
    switch(k){
        case 0:
        // ht will be directly used in calling function
            return ht;
        
        case 1:
            return wid;

        case 2:
            return dep;
        default:
        return ht;
    }
}

4. ostream: operator<<, istream: operator>>

These two functions is used to handle the output a class or input a class by cout, cint.

ostream& operator<<(ostream& str, const ThreeD t) {
	str << "[" << t.ht << ", " << t.wid << ", " << t.dep << "]";
	return str;
}

istream& operator>>(istream& str, ThreeD& t) {
	str >> t.ht >> t.wid >> t.dep;
	return str;
}

4. ofstream: operator<<, ifstream: operator>>

These two functions is used to handle the output a class or input a class by file.

ofstream& operator<<(ofstream& str, const ThreeD& t) {
	str << t.ht << " " << t.wid << " " << t.dep;
	return str;
}

ifstream& operator>>(ifstream& str, ThreeD& t) {
	str >> t.ht >> t.wid >> t.dep;
	return str;
}

5. Complete Code

The complete code is here:

// Operator Overloading

// console cin, cout
#include<iostream>  
// file in, out
#include<fstream>
using namespace std;

class ThreeD{
public:
    int ht;
    int wid;
    int dep;

    // default constructor
    ThreeD() {
        ht = wid = dep = 0;
    }

    // know knid of constructor
    ThreeD(int i, int j, int k): ht(i), wid(j), dep(k) {}
    int getVol(){ return ht * wid * dep; }

    // overload operator
    ThreeD operator+(ThreeD t);
    ThreeD operator*(ThreeD t);
    ThreeD operator++();                // prefix
    ThreeD operator++(int neverUsed);   // postfix
    int & operator[](int k);

    //friend: allow function to access private paramenter
    friend ostream& operator<<(ostream& str, const ThreeD t);
	friend istream& operator>>(istream& str, ThreeD& t);

};

ThreeD ThreeD::operator+(ThreeD t){
    ThreeD temp;
    temp.ht = ht;
    temp.wid = t.wid;
    temp.dep = dep + t.dep;
    return temp;
}

ThreeD ThreeD::operator*(ThreeD t){
    ThreeD temp;
    temp.ht = ht * t.ht;
    temp.wid = wid * t.wid;
    temp.dep = dep * t.dep;
    return temp;
}

// prefix
// complier knows that the operator without argument is prefix
ThreeD ThreeD::operator++(){
    ++ht;
    ++wid;
    ++dep;
    // this is a pointer pointing to the current object
    return *this;
}

// postfix
// complier knows that the operator with argument is postfix
// store the value first,which will be return at the end
// then, apply the increment.
ThreeD ThreeD::operator++(int neverUsed){
    ThreeD tmp = *this;
    ht++;
    wid++;
    dep++;
    return tmp;
}


// return by ref

// if defined in this way, it's read-only
// const int & ThreeD::operator[](int k)

    //The origianl object will be returned to the calling function.
	//No extra copying effort is needed.  It is faster than return by value,
	//which requires an extra copy to be created and returned to the calling function.
	//Because an object is returned, rather than a value, the function can appear
	//on the left side of an statement.
int & ThreeD::operator[](int k){
    switch(k){
        case 0:
        // ht will be directly used in calling function
            return ht;
        
        case 1:
            return wid;

        case 2:
            return dep;
        default:
        return ht;
    }
}

ostream& operator<<(ostream& str, const ThreeD t) {
	str << "[" << t.ht << ", " << t.wid << ", " << t.dep << "]";
	return str;
}

istream& operator>>(istream& str, ThreeD& t) {
	str >> t.ht >> t.wid >> t.dep;
	return str;
}

ofstream& operator<<(ofstream& str, const ThreeD& t) {
	str << t.ht << " " << t.wid << " " << t.dep;
	return str;
}

ifstream& operator>>(ifstream& str, ThreeD& t) {
	str >> t.ht >> t.wid >> t.dep;
	return str;
}



int main(){
    ThreeD t1(3,4,5), t2(10, 11, 12), t3, t4, t5, t6;
    int i1{ 10 };
    int i2{ 20 }, i3;
    i3 = i1 + i2;

    // complier will convert it into:
    // t3 = t1.operator+(t2);
    t3 = t1 + t2;

    // it's same as t4 = t1.operator*(t2);
    t4 = t1 * t2;

    // prefix
    t5 = ++t2;

    //postfix
    t6 = t2++;
    
    t1[2] = 100;
    cout << t1[2] << endl;
    cout << t1 << endl;

    cin >> t4;
    cout << t4 << endl;

    
    ofstream out("data1.txt");
    out << t1 << endl;
    //opearating system level
    out.close();

    ifstream in("data1.txt");
    in >> t1;
    cout << t1 << endl;
    in.close();

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值