国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

嵌入式C++開發(fā)詳解(六)

2019-11-08 02:00:15
字體:
供稿:網(wǎng)友

運算符重載

一、友元機制

1.友元介紹

·友元是一種允許非類成員函數(shù)訪問類的非公有成員的一種機制

·可以把一個函數(shù)指定為類的友元,也可以把整個類指定為另一個類的友元。

   友元函數(shù)

   友元類

2.友元函數(shù)

·友元函數(shù)在類作用域外定義,但它需要在類體中進行說明

·為了與該類的成員函數(shù)加以區(qū)別,定義的方式是在類中用關(guān)鍵字friend說明該函數(shù),格式如下:

      friend 類型  友元函數(shù)名(參數(shù)表)

友元的作用在于提高程序的運行效率

友元函數(shù)的注意事項:

·友元函數(shù)不是類的成員函數(shù),在函數(shù)體中訪問對象的成員,必須用對象名加運算符“.”加對象成員名。但友元函數(shù)可以訪問類中的所有成員(公有的、私有的、保護的),一般函數(shù)只能訪問類中的公有成員。

·友元函數(shù)不受類中的訪問權(quán)限關(guān)鍵字限制,可以把它放在類的公有、私有、保護部分,但結(jié)果一樣。

·某類的友元函數(shù)的作用域并非該類作用域。如果連友元函數(shù)不是另一類的成員函數(shù),則其作用域為另一類的作用域,否則與一般函數(shù)相同。

·友元函數(shù)破壞了面向?qū)ο蟪绦蝾惖姆庋b性,所有友元函數(shù)如不是為了必須使用則盡可能少用。或者用其他手段保護封裝性。

3.友元類

友元類的注意事項:

·友元關(guān)系是單向的

·友元關(guān)系不能被傳遞

·友元關(guān)系不能被繼承

代碼示例:

String.h;#ifndef _STRING_H_#define _STRING_H_ class String{public:    friend class StringTool;friend void PRint(const String &s1);  //友元函數(shù)String();String(char *str);~String();void Display();private:char *str_; };#endifString.cpp:#include <iostream>#include "String.h" using namespace std; String::String(){cout << "default constructor String!" << endl;}String::String(char *str){cout << "constructor String" << endl;int len = strlen(str) + 1;str_ = new char(len);memset(str_, 0, len);strcpy(str_, str);} String :: ~String(){cout << "destory String" << endl;} void String::Display(){cout << str_ << endl;} void print(const String& s1)//友元函數(shù){cout << s1.str_ << endl;} StringTool.h:#ifndef _STRINGTOOL_H_#define _STRINGTOOL_H_#include "String.h" class StringTool{public:void mystrcat(String& s1, String& s);}; #endifStringTool.cpp:#include <iostream>#include <string.h>#include "StringTool.h" void StringTool::mystrcat(String &s1, String &s){strcat(s1.str_, s.str_);} main.c:#include <iostream>#include "String.h"#include "StringTool.h"using namespace std; int main(){String s1("hello");print(s1);//String s2("world");//StringTool st;//st.mystrcat(s1, s2);//調(diào)用友元類 return 0;}

運行結(jié)果:

二、運算符重載

1.運算符重載介紹

·運算符重載允許把標準運算符(如+、—、*、/、<、>等)應用于自定義數(shù)據(jù)類型的對象

運算符重載的作用:

·直觀自然,可以提高程序的可讀性

·體現(xiàn)了C++的可擴充性

·運算符重載僅僅只是為了語法上的方便,它是另一種函數(shù)調(diào)用方式

·運算符重載,本質(zhì)上是函數(shù)重載

運算符重載的注意事項:

·不要濫用重載,本質(zhì)上是函數(shù)重載

2.運算符重載的實現(xiàn)

(1)成員函數(shù)重載

  · 成員函數(shù)原型格式:

     函數(shù)類型 Operator 運算符(參數(shù)表);

  ·成員函數(shù)定義的格式:

     函數(shù)類型 類名 :: operator 運算符(參數(shù)表)

     {

         函數(shù)體;

     }

(2)友元函數(shù)重載

  ·友元函數(shù)原型的格式:

friend 函數(shù)類型 operator運算符(參數(shù)表);

  ·友元函數(shù)定義的格式:

函數(shù)類型 函數(shù)類型 類名::operator 運算符(參數(shù)表)

{

    函數(shù)體;

}

3.運算符重載規(guī)則

·運算符重載不允許發(fā)明新的運算符

·不能改變運算符操作對象的個數(shù)

·運算符被重載后,其優(yōu)先級和結(jié)合性不會改變

·不能被重載的運算符

   作用域解析運算符 ::

   條件運算符   ?:

   直接成員訪問運算符   .

   類成員指針引用的運算符 .*

   sizeof運算符     sizeof

·成員函數(shù)重載和友元函數(shù)重載的選擇

  一般情況下,單目運算符最好重載為類的成員函數(shù);雙目運算符則最好重載為類的友元函

  數(shù)

  以下一些雙目運算符不能重載為類的友元函數(shù):= ()、[]、->

  類型轉(zhuǎn)換運算符只能以成員函數(shù)方式重載

  流運算符只能以友元的方式重載

 

4.++運算符的重載

(1)成員函數(shù)重載方式

(2)友元函數(shù)重載方式

代碼示例:

Integer.h:#ifndef _INTEGER_H_#define _INTEGER_H_ class Integer{public:    Integer();    Integer(int n);    ~Integer();    void Display() const;    Integer& operator++();    Integer operator++(int n);  //  friend Integer& operator++(Integer &i);   //友元函數(shù)重載方式  //  friend Integer operator++(Integer &i,int n);   //友元函數(shù)重載方式    operator int();private:    int n_;};#endif Integer.cpp:#include "Integer.h"#include <iostream> using namespace std; Integer :: Integer(){ } Integer :: Integer(int n) : n_(n){ } Integer :: ~Integer(){ } void Integer :: Display() const{    cout << n_ << endl;} Integer& Integer :: operator++(){    cout << "++i" << endl;     ++n_;     return *this;}Integer Integer :: operator++(int n){    cout << "i++" << endl;     Integer tmp(n_);     n_++;     return tmp;} #if 0 Integer& operator++(Integer& i){    cout << "friend ++i" << endl;    ++i.n_;     return i;} Integer operator++(Integer& i,int n){    cout << "friend i++" << endl;     Integer temp(i.n_);    i.n_++;    return temp;} #endif Integer :: operator int(){    return n_;} Main.c:#include "Integer.h"#include <iostream> using namespace std; Integer :: Integer(){ } Integer :: Integer(int n) : n_(n){ } Integer :: ~Integer(){ } void Integer :: Display() const{    cout << n_ << endl;} Integer& Integer :: operator++(){    cout << "++i" << endl;     ++n_;     return *this;}Integer Integer :: operator++(int n){    cout << "i++" << endl;     Integer tmp(n_);     n_++;     return tmp;} #if 0 Integer& operator++(Integer& i){    cout << "friend ++i" << endl;    ++i.n_;     return i;} Integer operator++(Integer& i,int n){    cout << "friend i++" << endl;     Integer temp(i.n_);    i.n_++;    return temp;} #endif Integer :: operator int(){    return n_;} 

運行結(jié)果請自行實踐~

 

5.!運算符重載

成員函數(shù)原型:

   bool operator!() const;

成員函數(shù)定義:

   bool String :: operator!()  const

   {

       return strlen(str_)  ! = 0;

   }

6.賦值運算符重載

成員函數(shù)原型:

String& operator = (const String& other);

成員函數(shù)定義:

String& String :: operator = (const String& other)

{

    if(this == &other)

    {

        return * this;

    }

 

    int len = strlen(other.str_) + 1;

 

    delete[] str_;

 

    str_  = new char[len];

    memset(str_,0,len);

    strcpy(str_,other.str_);

}

 

7.[]運算符重載

成員函數(shù)原型:

(1)char& operator[](unsigned int index);

(2)const char& operator[](unsigned int index) const;

成員函數(shù)定義:

(1)char& String :: operator[](unsigned int index)

{

    cout << "no const" << endl;

 

    //return str_[index];

    return const_cast<char&>(static_cast<const String&>(*this)[index]);

}

 

(2)const char& String :: operator[](unsigned int index) const

{

    cout << "const[]" << endl;

 

    return str_[index];

}

8.+運算符重載

成員函數(shù)原型:

friend String operator+(const String &s1,const String &s2);

成員函數(shù)定義:

String operator+(const String& s1,const String& s2)

{

#if 0

    int len = strlen(s1.str_) + strlen(s2.str_) + 1;

    char * newstr = new char[len];

    memset(newstr,0,len);

    strcpy(newstr,s1.str_);

    strcat(newstr,s2.str_);

    String temp(newstr);

 

    delete newstr;

#endif     //實現(xiàn)+=后可以直接使用下面幾行代碼

 

    String temp(s1);

    temp += s2;

 

    return temp;

 

}

9.+=運算符重載

成員函數(shù)原型:

String& operator+=(const String& other);

成員函數(shù)定義:

String& String :: operator+=(const String& other)

{

    int len = strlen(str_) + strlen(other.str_) + 1;

    char * newstr = new char[len];

    memset(newstr,0,len);

    strcpy(newstr,str_);

    strcat(newstr,other.str_);

    delete[] str_;

    str_ = newstr;

 

    return * this;

}

10.流運算符重載

·為什么一定要使用友元函數(shù)進行重載?

如果是重載雙目操作符(即為類的成員函數(shù)),就只要設置一個參數(shù)作為右側(cè)運算量,而左側(cè)運算量就是對象本身

而 >> 或<<左側(cè)運算量是 cin或cout而不是對象本身,所以不滿足后面一點,就只能申明為友元函數(shù)了

成員函數(shù)原型:

(1)friend ostream& operator<<(ostream& out,const String& s);

(2)friend istream& operator>>(istream& in,String& s);

成員函數(shù)定義:

(1)ostream& operator<<(ostream& out,const String& s)

{

    out << s.str_;

 

    return out;

}

 

(2)istream& operator>>(istream& in,String& s)

{

    char buffer[1024];

    in >> buffer;

    int len  = strlen(buffer) + 1;

    delete[] s.str_;

    s.str_ = new char[len];

 

    strcpy(s.str_,buffer);

 

    return in;

}

11.類型轉(zhuǎn)換運算符重載

·必須是成員函數(shù),不能是友元函數(shù)

·沒有參數(shù)(操作數(shù)是什么?)

·不能指定返回類型(其實已經(jīng)指定了)

·函數(shù)原型:operator 類型名();

Integer :: operator int()

{

    return n_;

}

 

int main(void)

{

Integer n(100);

n = 200;

n.Display();

 

int sum = add(n,100);

cout << sum << endl;

 

int x = n;

int v = static cast<int>(n);

 

return 0;

}

12.->運算符重載

#include <iostream>

using namespace std;

 

class DBHelper

{

public:

  DBHelper()

  {

   cout<<"DB ..."<<endl;

  }

  ~DBHelper()

  {

   cout<<"~DB ..."<<endl;

  }

 

  void Open()

  {

   cout<<"Open ..."<<endl;

  }

 

  void Close()

  {

   cout<<"Close ..."<<endl;

  }

 

  void Query()

  {

   cout<<"Query ..."<<endl;

  }

};

 

class DB

{

public:

  DB()

  {

   db_ = new DBHelper;

  }

 

  ~DB()

  {

   delete db_;

  }

 

  DBHelper* operator->()

  {

   return db_;

  }

private:

  DBHelper* db_;

};

 

 

int main(void)

{

  DB db;

  db->Open();

  db->Query();

  db->Close();

  return 0;

}

13.new/delete

(1)operator new

(1) 只分配所要求的空間,不調(diào)用相關(guān)對象的構(gòu)造函數(shù)。當無法滿足所要求分配的空間時,則 ->如果有new_handler,則調(diào)用new_handler,否則

  ->如果沒要求不拋出異常(以nothrow參數(shù)表達),則執(zhí)行bad_alloc異常,否則

 ->返回0

(2) 可以被重載

(3) 重載時,返回類型必須聲明為void*

(4) 重載時,第一個參數(shù)類型必須為表達要求分配空間的大小(字節(jié)),類型為size_t

(5) 重載時,可以帶其它參數(shù)

void * operator new(size_t size)

{

cout <<“void * operator new(size_t size size)” << endl;

void *p = malloc(size);

return p;

}

void operator delete(void *p)

{

cout <<“void operator delete(void *p)” << endl;

free(p);

}

(2)new operator

new operator 

(1)調(diào)用operator new分配足夠的空間,并調(diào)用相關(guān)對象的構(gòu)造函數(shù) 

(2)不可以被重載

(3)placement new(不分配內(nèi)存+構(gòu)造函數(shù)的調(diào)用)


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 星子县| 九江县| 凭祥市| 安庆市| 洞口县| 海原县| 澎湖县| 临湘市| 常熟市| 白玉县| 香港| 定结县| 齐齐哈尔市| 东明县| 南部县| 图片| 吉林市| 安塞县| 依安县| 宁德市| 通州市| 女性| 弥渡县| 芷江| 英山县| 疏勒县| 克山县| 广西| 汕尾市| 深州市| 南和县| 关岭| 平谷区| 资阳市| 昭觉县| 确山县| 南投县| 龙岩市| 长沙县| 科技| 玉田县|