1. 程式人生 > 其它 >C++學習日記day5

C++學習日記day5

技術標籤:C++c++字串

運算子過載
運算子:單目/雙目/三目
過載:(函式過載) 名稱相同,作用不同(“一名多用”)
* 乘號/指標
& 引用/取地址
<<,>> 位移運算子/輸出

.  ::  ?: *(指標) sizeof

CPoint (3,4)
c1 ,c2; c1+c2

不能改變優先順序,結合性
不能改變所需要的運算元
不能建立新的運算子

單目運算子 ++ – (前置/後置)

前置:
運算子過載本質是一個成員函式;
CPoint c1;
c1++;
成員函式
<返回值> operator <運算子>(<引數列表>)

CPoint operator++(); (this指標)
友元函式
friend <返回值> operator <運算子>(<引數列表>)
friend CPoint operator++(CPoint &c)

單目運算子 ++ – (前置/後置)

int a = 1;

a++ 先賦值 後++ int b = a++;
++a 先++ 後賦值 int b = ++a;

前置:
運算子過載本質是一個成員函式;
CPoint c1;
c1++;
成員函式
<返回值> operator <運算子>(<引數列表>)
CPoint operator++(); (this指標)

友元函式
friend <返回值> operator <運算子>(<引數列表>)
friend CPoint operator++(CPoint &c)
後置:
成員函式
<返回值> operator <運算子>(<引數列表>)
CPoint operator++(int); (this指標)
int沒有任何實際意義,僅僅是後置單目運算子的標誌
友元函式
friend <返回值> operator <運算子>(<引數列表>)
friend CPoint operator++(CPoint &c,int)
1.引數列表 需要加個int作為識別符號
2.實現:先用一箇中介物件儲存原始的值

雙目運算子: + - * /
c = c1+c2
成員函式:
<返回值> operator <運算子>(<引數列表>)
Complex operator+(Complex c2);
引數列表中引數表示右運算元,左運算元用this指標操作
友元函式:
friend Complex operator+(Complex c1,Complex c2)

用成員函式時候 總會有一個this指標指向其中一個運算元;
用友元函式時候 沒有this指標,需要通過引數列表將所有的運算元傳進去

之前的 ++ – + - * / 所有的運算元都在自己的控制範圍之內
所以友元/成員 都可以使用

成員會省略一個左運算元 如果運算元不在自己的控制範圍,那就不能用成員函式
(友元比較規範,需要幾個運算元就傳幾個進去)
友元函式常用於運算子左右運算元不同的情況

賦值運算子 =
一般情況下,系統為每一個類都生成一個預設的賦值運算子

淺拷貝的問題出在預設建構函式 解決方法:深拷貝(自己寫拷貝構造)
指標懸掛問題出在預設賦值運算子 解決方法:自己過載賦值運算子

注意點:
	1不可以用友元過載
	2不可以被繼承
	3不可以宣告為虛擬函式
成員變數有指標/有賦值操作,需要自己過載賦值運算子

陣列下標運算子 []
不能使用友元過載

#include <iostream>
using namespace std;

class myArray
{
private:
    int m_length;
    int *m_space;
public:
    myArray(int length);
    myArray(const myArray& obj);
    ~myArray();
 
public:
    void setData(int index, int value);
    int getData(int index);
    int length();

    //函式返回值當左值,需要返回一個引用
    //應該返回一個引用(元素本身) 而不是一個值
    int& operator[](int i);

	 //過載=
    myArray& operator=(myArray &a1);

};

myArray::myArray(int length)
{
  if (length < 0)
  {
    length = 0; 
  }
 
  m_length = length;
  m_space = new int[m_length];
}
myArray::myArray(const myArray& obj)
{

	this->m_length = obj.m_length;
	this->m_space = new int[this->m_length]; //分配記憶體空間
 
	for (int i=0; i<m_length; i++) //陣列元素複製
	{
		this->m_space[i] = obj.m_space[i];
	}

}

myArray::~myArray()
{
  if (m_space != NULL)
  {
    delete[] m_space;
    m_space = NULL;
    m_length = -1;
  }
}

void myArray::setData(int index, int value)
{
	m_space[index] = value;
}

int myArray::getData(int index)
{
	return m_space[index];
}

int myArray::length()
{
	return m_length;
}

int& myArray::operator[](int i)
{
	if(i>m_length)
	{
		cout << "陣列下標越界" << endl;
	}
	return m_space[i];
}

myArray& myArray::operator=(myArray &a1)
{
	if(this->m_space != NULL)
	{
		delete[] m_space;
		m_space = NULL;
		m_length = 0;
	}
	this->m_length = a1.m_length;
	this->m_space = new int[m_length];

	for (int i=0; i<m_length; i++)
	{
		//m_space[i] = a1.m_space[i];
		m_space[i] = a1[i];
	}
	return *this;


}

int main()
{
	myArray a1(10);
	for(int i = 0;i < a1.length();i++)
	{
		a1.setData(i,i);
	}
	for (int i=0; i<a1.length(); i++)
	{
		cout<<a1.getData(i)<<" ";
	}
	cout<<endl;

	myArray a2 = a1;
	cout<<"\n列印陣列a2: ";
	for (int i=0; i<a2.length(); i++)
	{
	  cout<<a2.getData(i)<<" ";
	}
	cout<<endl;

	myArray a3(5);

	a3 = a1;
	a3 = a2 = a1; 
	cout<<"\n列印陣列a3: ";
	for (int i=0; i<a3.length(); i++)
	{
		cout<<a3[i]<<" ";
	}



	system("pause");
	return 0;

}

小test
字串類的編寫:

#include <iostream>
#include <cstring>
using namespace std;

class MyString
{
private:
       int m_len;
       char *m_p;

public:
    MyString(int len = 0);
    MyString(const char *p);
    MyString(const MyString & str);
    ~MyString();

public:
    MyString & operator = (const char *p);
    MyString & operator = (const MyString &str);

    char & operator [](const int index);

    bool operator == (const char * p) const;
    bool operator == (const MyString & str) const;
    bool operator != (const char * p) const;
    bool operator != (const MyString & str) const;

    bool operator < (const char * p) const;
    bool operator < (const MyString & str) const;
    bool operator > (const char * p) const;
    bool operator > (const MyString & str) const;

public:
    char *c_str()
    {
        return m_p;
    }
    const char *c_str2()
    {
        return m_p;
    }

    int length()
    {
        return m_len;
    }

    friend ostream & operator << (ostream & out, const MyString & str);
    friend istream & operator >> (istream & in, const MyString & str);
};

MyString::MyString(int len)
{

    m_len = len;
    m_p = new char [m_len + 1];
    cout << "1個引數的建構函式被呼叫!" << endl;
}

MyString::MyString(const char * p)
{
    if (p == NULL)
    {
        m_len = 0;
        m_p = new char [1];
        m_p[0] = '\0';
    }
    else
    {
        m_len = strlen(p);
        m_p = new char [m_len + 1];
        strcpy(m_p, p);
    }
    cout << "帶有1個常量字串的建構函式被呼叫!" << endl;
}

MyString::MyString(const MyString & str)
{
    if (str.m_len == 0)
    {
        m_len = 0;
        m_p = new char [1];
        m_p[0] = '\0';
    }
    else
    {
        m_len = str.m_len;
        m_p = new char [m_len + 1];
        strcpy(m_p, str.m_p);
    }
    cout << "拷貝建構函式被呼叫!" << endl;
}

MyString::~MyString()
{
    if (m_p)
    {
        delete [] m_p;
        m_p = NULL;
        m_len = 0;
    }
    cout << "解構函式被呼叫!" << endl;
}

MyString & MyString::operator = (const char * p)
{
    if (m_p)
    {
        delete [] m_p;
    }

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

    cout << "常量字串賦值函式被呼叫!" << endl;
    return *this;
}

MyString & MyString::operator = (const MyString & str)
{
    if (m_p)
    {
        delete [] m_p;
    }
    if (m_p == NULL)
    {
        m_len = 0;
        m_p = new char [1];
        m_p[0] = '\0';
    }
    else
    {
        m_len = str.m_len;
        m_p = new char [m_len + 1];
        strcpy(m_p, str.m_p);
    }

    cout << "物件賦值函式被呼叫!" << endl;
    return *this;
}

char & MyString::operator [](const int index)
{
    cout << "陣列下標運算子過載函式被呼叫!" << endl;
    return m_p[index];
}

bool MyString::operator == (const char * p) const
{
    cout << "常量字串 == 運算子過載函式被呼叫!" << endl;
    if (strcmp(m_p, p) == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool MyString::operator == (const MyString & str) const
{
    cout << "物件 == 運算子過載函式被呼叫!" << endl;
    return m_p == str.m_p;
}

bool MyString::operator != (const char * p) const
{
    cout << "常量字串 != 運算子過載函式被呼叫!" << endl;
    return !(m_p == p);
}

bool MyString::operator != (const MyString & str) const
{
    cout << "物件 != 運算子過載函式被呼叫!" << endl;
    return !(m_p == str.m_p);
}

bool MyString::operator < (const char * p) const
{
    cout << "常量字串 < 運算子過載函式被呼叫!" << endl;
    if (strcmp(m_p, p) < 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool MyString::operator < (const MyString & str) const
{
    cout << "物件 < 運算子過載函式被呼叫!" << endl;
    if (strcmp(m_p, str.m_p) < 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool MyString::operator > (const char * p) const
{
    cout << "常量字串 > 運算子過載函式被呼叫!" << endl;
    if (strcmp(m_p, p) > 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool MyString::operator > (const MyString & str) const
{
    cout << "物件 < 運算子過載函式被呼叫!" << endl;
    if (strcmp(m_p, str.m_p) > 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

ostream & operator << (ostream & out, const MyString & str)
{
    out << str.m_p << " ";

    return out;
}

istream & operator >> (istream & in, const MyString & str)
{
    in >> str.m_p;

    return in;
}

int main()
{
    MyString str1(5);
    cout << "請輸入長度為5的字串:" << endl;
    cin >> str1;
    cout <<"str1: ";
    cout << str1 << endl;
    cout << "_______________________________________" << endl;

    MyString str2("Hello World!");
    cout <<"str2: ";
    cout << str2 << endl;
    cout << str2[11] << endl;
    cout << "_______________________________________" << endl;

    MyString str3 = str1;
    cout <<"str3: ";
    cout << str3 << endl;
    cout << "_______________________________________" << endl;

    MyString str4;
    str4 = str2;
    cout <<"str4: ";
    cout << str4 << endl;
    cout << "_______________________________________" << endl;

    cout << "str1 = str2? : "<< (str1 == str3) << endl;
    cout << "_______________________________________" << endl;

    cout << "str2 = str4? : "<< (str2 != str4) << endl;
    cout << "_______________________________________" << endl;

    cout << "str1 > str3? : "<< (str1 > str3) << endl;
    cout << "_______________________________________" << endl;

    cout << "str3 < str4? : "<< (str3 < str4) << endl;
    cout << "_______________________________________" << endl;

    cout << "str1 = hello? : "<< (str1 == "hello") << endl;
    cout << "_______________________________________" << endl;

    cout << "str2 = hello? : "<< (str2 != str4) << endl;
    cout << "_______________________________________" << endl;

    cout << "str1 > hello world? : "<< (str1 > str3) << endl;
    cout << "_______________________________________" << endl;

    cout << "str3 < hello world? : "<< (str3 < str4) << endl;
    cout << "_______________________________________" << endl;

    return 0;
}