c++ 程序设计 week4 运算符重载

运算符重载

这一周的内容主要讲运算符重载, 但是如何设计返回值类型,以及是否需要采用成员函数都是很重要的。


1. 赋值运算符重载

T & operator=(T  &a); 

与copy constructor类类似, 但是存在返回值.

(1) 成员函数:只能定义成成员函数。

(2)返回值:而且返回值类型必须是引用,才能符合我们对等号的直观理解。(a = b) = c 还会将a改变, 所以我们需要返回T&。

(3)类内存在指针时需要注意如果右边赋值和本身相同时,不需要重新赋值; 而且如果原来为空指针,那么也可以直接赋值,  以上两种类型都需要先判断,以防delete时出现错误.



2. 运算符重载位友元函数

T operator+(const T &a, const T &b)

如果我们把函数重载为外部函数, 那么在内部设置为友元函数可以访问成员的私有member.



3. 流输入,输出函数

输出:

ostream & operator<< (ostream &os, const T & a);

(1)返回类型: &ostream, (保证流的一致性)

(2)外部重载函数, 因为我们需要 ostream << , 如果设置为内部函数则无法调用.

输入函数类似.


4. ++ ,--

前置++T: T operator++()

后置T++: T operator++(int)



所以下面用了国外一门课的例子.

例子MyString

#MyString.h
#ifndef __MYSTRING_H__
#define __MYSTRING_H__
#include <iostream>

using namespace std;

class MyString {

    public:

	// default constructor
	MyString();

	// constructor
	MyString(const char* p);

	// destructor
	~MyString();

	// copy constructor 
	MyString(const MyString& s);

	// copy assignment
	MyString& operator=(const MyString& s);

	// returns the length of the string
	int length() const { return len; }
	
	friend int operator==(const MyString& s1,const MyString& s2);
	friend int operator!=(const MyString& s1,const MyString& s2);
	
	friend int operator>(const MyString& s1,const MyString& s2);
	friend int operator<(const MyString& s1,const MyString& s2);

	friend int operator>=(const MyString& s1,const MyString& s2);
	friend int operator<=(const MyString& s1,const MyString& s2);
	MyString& operator+=(const MyString &s);

	// put-to operator
	friend ostream& operator<<(ostream& os, const MyString& s);

	// get-from operator
	friend istream& operator>>(istream& is, MyString& s);

	// operator[]
	char& operator[](int i);

	// operator[] const
	const char& operator[](int i) const;

    private:

	char* data;

	int len;
};

MyString operator+(const MyString& s1, const MyString& s2);
#endif

#MyString.cpp
#include <cstring>
#include <cstdio>

#include "mystring.h"

// default constructor

MyString::MyString() 
{
    data = new char[1];
    data[0] = '\0';   
    len = 0;
}

// constructor

MyString::MyString(const char* p)
{

    if (p) {
	len = strlen(p);
	data = new char[len+1];
	strcpy(data, p);
    } else {
	data = new char[1];
	data[0] = '\0';
	len = 0;
    }
}

// destructor

MyString::~MyString() 
{
    delete[] data;
}

// copy constructor 

MyString::MyString(const MyString& s) 
{
    len = s.len;  
    data = new char[len+1];
    strcpy(data, s.data);
}

// copy assignment

MyString& MyString::operator=(const MyString& rhs)
{
#ifdef BASIC4TRACE
    fprintf(stderr, "BASIC4TRACE: (%p)->op=(const MyString&)\n", this);
#endif

    if (this == rhs) {
	return *this;
    }

    // first, deallocate memory that 'this' used to hold

    delete[] data;

    // now copy from rhs
    
    len = rhs.len;

    data = new char[len+1];
    strcpy(data, rhs.data);

    return *this;
}
//+=operator
MyString& MyString::operator+=(const MyString &s)
{
	len = len + s.len;
	char *temp = new char[len+1];
	strcpy(temp,data);
	strcat(temp,s.data);
	delete[] data;
	data = temp;
	return *this;
}

// operator+

MyString operator+(const MyString& s1, const MyString& s2)
{
#ifdef BASIC4TRACE
    fprintf(stderr, 
	    "BASIC4TRACE: op+(const MyString&, const MyString&)\n");
#endif
    MyString temp = s1;
    temp += s2;
    return temp;
}

// put-to operator

ostream& operator<<(ostream& os, const MyString& s)
{
    os << s.data;
    return os;
}

// get-from operator

istream& operator>>(istream& is, MyString& s)
{
    // this is kinda cheating, but this is just to illustrate how this
    // function can work.
    
    string temp;
    is >> temp;

    delete[] s.data;

    s.len = strlen(temp.c_str());
    s.data = new char[s.len+1];
    strcpy(s.data, temp.c_str());

    return is;
}

// operator[] - in real life this function should be declared inline

char& MyString::operator[](int i) 
{
    return data[i];
}

// operator[] const - in real life this should be inline

const char& MyString::operator[](int i) const
{
    // illustration of casting away constness
    return ((MyString&)*this)[i];
}


int operator==(const MyString& s1,const MyString& s2)
{
	return (strcmp(s1.data,s2.data)==0);
}

int operator!=(const MyString& s1, const MyString& s2)
{
	return (strcmp(s1.data,s2.data)!=0);
}

int operator<(const MyString& s1,const MyString& s2)
{
	return (strcmp(s1.data,s2.data)<0);
}

int operator>(const MyString& s1,const MyString& s2)
{
	return(strcmp(s1.data,s2.data)>0);
}
int operator<=(const MyString& s1,const MyString& s2)
{
	return(strcmp(s1.data,s2.data)<=0);
}
int operator>=(const MyString& s1,const MyString& s2)
{
	return(strcmp(s1.data,s2.data)>=0);
}















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值