淺析C說話位域和位段。本站提示廣大學習愛好者:(淺析C說話位域和位段)文章只能為提供參考,不一定能成為您想要的結果。以下是淺析C說話位域和位段正文
C++劃定有四個運算符 =, ->, [], ()弗成所以全局域中的重載(即不克不及重載為友員函數),這是為何呢?
如今先說說賦值運算符“=”的重載
C++劃定賦值運算符“=”只能重載為類的非靜態成員函數,而弗成以重載為類的友元函數。
不克不及重載為類的靜態成員應當比擬輕易懂得,由於靜態成員函數是屬於全部類的,不是屬於某個對象的,它只能去操作類靜態數據成員。而賦值運算符“=”是基於對象操作的。
那末為何賦值運算符弗成以重載為類的友元函數?像異樣都是雙目運算符的+為何它便可以呢?
在評論辯論這成績之前,先看一測試的法式:
#include <iostream>
using namespace std;
class A
{
private:
int x;
public:
A(){x=99;}
A(int xx)
{
cout<<"Call A(int xx)"<<endl;
x = xx;
}
};
int main()
{
A a;
a = 7;
}
法式履行成果為:
Call A(int xx)
解釋履行a = 7這法式語句時,法式去挪用類A中的帶參結構函數。
在類A中參加一賦值運算重載成員函數,以下:
#include <iostream>
using namespace std;
class A
{
private:
int x;
public:
A(){x=99;}
A(int xx)
{
cout<<"Call A(int xx)"<<endl;
x = xx;
}
A operator=(int xx) //重載賦值運算符運算
{
cout<<"Call A operator=(int xx)"<<endl;
x = xx;
return *this;
}
};
int main()
{
A a;
a = 7;
}
法式運轉成果:
Call A operator=(int xx)
解釋在類A中曾經有響應賦值運算符重載函數的時刻,履行賦值語句a = 7;法式會去挪用類A中響應的賦值運算符重載函數,而不會像下面本來那樣去挪用有參結構函數。
在此,我們可以對C++規矩做出以下的斷定:
當類中沒有界說賦值運算符重載成員函數時(留意,在不決義形參數據類型為該類類型的賦值運算符重載函數時,編譯器會主動生成參加),當法式履行到某一賦值語句時,法式就會挪用與賦值語句中右值類型婚配的結構函數,而把這右值看成此結構函數的實參。像最後的賦值語句a = 7,履行時,現實做的操作是a(7)。而當類中有界說賦值運算符重載成員函數,履行賦值語句時,法式就只會去挪用響應的賦值運算符重載函數。
當明確下面的規矩後,如今便可以回過去,評論辯論為何賦值運算符弗成以重載為類的友元函數了。
我們曉得友元函數不是類的成員函數,它只是類的“同伙“,具有拜訪把它聲明為“同伙”的類的數據成員的權限罷了。
那末當把賦值運算符重載為類的友員函數,在法式中履行類對象的賦值語句時,法式就會湧現兩種抵觸的選擇。
1、由於它以為類中並沒有重載賦值運算符的成員函數,所以它依據C++的規矩,會去挪用響應的結構函數。
2、然則在全局裡,我們曾經重載了參數類型為此類類型的賦值運算符函數,而這賦值語句恰好和這函數婚配上了,依據C++的規矩,也會去挪用這函數。
法式是不許可有抵觸不肯定選擇的,所以當賦值運算符重載為類的友元函數時,編譯器就會提醒毛病。
關於剩下的3個運算符 ->, [], () 為何不克不及重載為友元函數,也是跟下面一樣的事理。即編譯器發明當類中沒有界說這3個運算符的重載成員函數時,就會本身參加默許的運算符重載成員函數。
例當類A中沒有界說運算符->的重載成員函數,然則我們依然可以對類A對象指針用->的情勢挪用指針指向的對象裡的成員。像類A裡有成員函數f(),當
A a;
A* p = &a;
p->f(); //固然類A中沒有本身界說運算符->重載成員函數,但這裡仍可如許應用
但是,當我們把->運算符重載為類A的友元函數時,法式就會湧現跟把賦值運算符重載友元一樣的情形,即發生抵觸性。
聲明:以上僅為小我看法