1. 程式人生 > >C++回顧之前置++、後置++、不等號!及賦值運算子過載

C++回顧之前置++、後置++、不等號!及賦值運算子過載

        運算子過載的主要目的是為了讓類物件能像普通資料型別一樣能夠進行加減乘除,自加自減等操作,非常直觀方便。現在來回顧C++的自加減(分前置與後置)以及不等號非運算子,賦值運算子的過載。

        1 ++過載

        (1)前置++運算子的過載方式:

        成員函式的過載: 函式型別& operator++()

        友元函式的過載:friend 函式型別& operator++(類型別& )

        (2)後置++運算子的過載方式:

        成員函式的過載:函式型別& operator++(int)

        友元函式的過載:friend 函式型別& operator++(類型別&, int)

        注意,為了區分前置++與後置++的區別,需要在引數後增加一個"int"以示區分。含有"int"的過載方式為後置++,否則為前置++。前置--與後置--類似用法。前面說過,成員函式與友元函式的過載如果同時存在時,會先呼叫成員函式的過載,但是在++或--時,成員函式與友元函式的過載是不能同時存在的。

        下面舉一個例子:

#ifndef _INTEGER_H_
#define _INTEGER_H_

class Integer
{
public:
    Integer(int n);
    ~Integer();
    void Display();

    Integer& operator++(); //成員方式過載前置++
    Integer& operator++(int); //成員方式過載後置++

    friend Integer& operator++(Integer& i);//友元函式過載前置++
    friend Integer& operator++(Integer& i, int);//友元函式過載後置++

    
private:
    int n_;
};

#endif
  

        下面是它們的具體程式碼實現:

#include "Integer.h"

Integer::Integer(int n):n_(n){}

Integer::~Integer(){}

void Integer::Display() const
{
     cout << n_ << endl;
}

//最好優先使用成員函式過載,

//成員函式過載前置++
Integer& Integer::operator++()
{
    ++n_;
    return *this;
}

//成員函式過載後置++
Integer& Integer::operator++(int)
{
    Integer tmp(n_);
    ++n_;
    return tmp;
}

//友元過載前置++
Integer& operator++(Integer& i)
{
    ++i.n_;
    return i;
}

//友元過載後置++
Integer& operator++(Integer& i, int)
{
    Integer tmp(i.n_);
    ++i.n_;
    return tmp;
}

        關於!及=賦值運算子的過載以String類進行說明:

         下面是String類的定義:

#ifndef STRING_H_
#define STRING_H_

class String
{
public:
    explicit String(const char *str="");
    String(const String& other);
    ~String();

    //應用於s="abc";的情況
    String& operator=(const char *str);//過載=

    bool operator!() const; //過載!

    void Display() const;

private:
    char* str_;
    char* AllocAndCopy(const char* str); 
};

#endif

        下面是具體實現:

#include <string.h>
#include <iostream>
#include "String.h"
using namespace std;

String::String(const char *str)
{
    str_ = AllocAndCopy(str);
}

String::~String()
{
    delete [] str_;
}

char* String::AllocAndCopy(const char* str)
{
    int len = strlen(str)+1;
    char* newstr = new char[len];
    memset(newstr, 0, len);
    strcpy(newstr, str);

    return newstr;
}


//深拷貝,copy assign
String& String::operator=(const String& other)   //s1 = s2
{
    if( this == &other)
        return *this;
    
    delete [] str_;
    str_ = AllocAndCopy(other.str_);
    return *this;
}

String& String::operator=(const char* str)  //s1="abc"
{
    delete []  str_;
    str_ = AllocAndCopy(str);
    return *this;
}

bool String::operator!() const
{
    return (strlen(str_) != 0 )
}

void String::Display() const
{
    cout << str_ << endl;
}

        針對String類寫的一個簡單的用例:

#include "String.h"
#include <iostream>
using namespace std;

int main()
{
    String s1("abc");
    String s2(s1);//copy.
    String s3;//帶預設引數
    
    s3 = s1; //呼叫賦值運算子
    s3.Display();


//預設的處理方式為:將字串構造成String類物件,再賦值至s3,如果在建構函式前加上explicit宣告,則會發生編譯錯誤。解決的方式需要過載一個引數為const char *的等號運算子即可
    s3 = "xxx"; //呼叫引數為const char *的賦值運算子
    
    String s4;
    bool notempty;
    notempty = !s4; 
    cout << notempty << endl; //1

    s4 = "aaa";
    notempty = !s4;
    cout << notempty << endl; //0

    return 0;
    
}