靜態成員函數訪問非靜態數據成員
⑴ 靜態成員函數怎麼引用該類中的非靜態成員函數
最佳答案,感覺有些沒說明白,是說靜態成員函數調用了原類的普通成員函數拷貝構造函數和析構函數么?修改了下代碼,大致可以看清:
#include<iostream>
using namespace std;
class Myclass
{
private:
int m; //非靜態數據成員
static int n; //靜態數據成員
public:
Myclass(); //構造函數
Myclass(Myclass &r); //拷貝構造函數
static int getn(Myclass a); // 靜態成員函數
~Myclass(); //析構函數
};
Myclass::Myclass()
{
m = 10;
cout << "調用構造函數" << endl;
}
Myclass::Myclass(Myclass &r)
{
m = r.m;
cout << "調用拷貝構造函數" << endl;
}
Myclass::~Myclass()
{
cout << "調用析構函數" << endl;
}
int Myclass::getn(Myclass a)
{
cout << a.m << endl; // 通過類間接使用 非靜態數據成員
return n; // 直接使用 靜態數據成員
}
int Myclass::n = 100; // 靜態數據成員初始化
void main()
{
Myclass app1;
cout << app1.getn(app1) << endl; // 利用對象引用靜態函數成員
cout << Myclass::getn(app1) << endl; // 利用類名引用靜態函數成員
system("pause");
}
這里還有個改來的例子,原例子是講靜態成員函數調用靜態成員變數的。網址:網頁鏈接
我在這里再構造一個普通成員函數,用靜態成員函數調用它,碰到普通成員函數只能通過對象調用的問題,因此在靜態成員函數中定義了一個默認值的對象(面積是0.不會計數圖形個數),但是每次這個對象銷毀後(即這個靜態成員函數調用之後)系統會調析構函數,使圖形計數減1,所以我在這里強行加1.最終編譯運行是可以的,可以參考下。
#include <iostream>
using namespace std;
class CRectangle
{
private:
int w=0, h=0;
static int totalArea; //矩形總面積
static int totalNumber; //矩形總數
public:
CRectangle() {};
CRectangle(int w_, int h_);
CRectangle(CRectangle & r);
~CRectangle();
void PrintCRectangle();
static void PrintTotal();
};
CRectangle::CRectangle(int w_, int h_)
{
w = w_; h = h_;
totalNumber++; //有對象生成則增加總數
totalArea += w * h; //有對象生成則增加總面積
}
CRectangle::CRectangle(CRectangle & r)
{
totalNumber++;
totalArea += r.w * r.h;
w = r.w; h = r.h;
}
CRectangle::~CRectangle()
{
totalNumber--; //有對象消亡則減少總數
totalArea -= w * h; //有對象消亡則減少總而積
}
void CRectangle::PrintCRectangle()
{
cout << this->totalNumber << "," << this->totalArea << endl;
}
void CRectangle::PrintTotal()
{
CRectangle a;
/*cout << totalNumber << "," << totalArea << endl;*/
a.PrintCRectangle();
totalNumber++;
}
//必須在定義類的文件中對靜態成員變數進行一次聲明 //或初始化,否則編譯能通過,鏈接不能通過
int CRectangle::totalNumber = 0;
int CRectangle::totalArea = 0;
int main()
{
CRectangle r1(1, 1);
CRectangle *r2 = new CRectangle(2, 2);
CRectangle r3(r1);
//cout << CRectangle::totalNumber; //錯誤,totalNumber 是私有
CRectangle::PrintTotal();
r2->PrintTotal();
r3.PrintTotal();
delete r2;
CRectangle::PrintTotal();
r1.PrintTotal();
r3.PrintTotal();
return 0;
}
再改一個版本,仿照最佳答案,在靜態成員函數中參數可以是類的對象,則在函數中不再定義類的對象,直接使用對象調用類的普通成員函數。由於這樣做在調用靜態成員函數時會對類對象初始化,調用構造函數(調用拷貝構造函數),則會對面積加和,計數會加1,而此函數調用結束,還會調用析構函數,會將面積減小,計數減1,所以會在下面的一些函數中加一些處理。最終結果,和上面是對得上的。
#include <iostream>
using namespace std;
class CRectangle
{
private:
int w=0, h=0;
static int totalArea; //矩形總面積
static int totalNumber; //矩形總數
public:
CRectangle() {};
CRectangle(int w_, int h_);
CRectangle(CRectangle & r);
~CRectangle();
void PrintCRectangle();
static void PrintTotal(CRectangle a);
};
CRectangle::CRectangle(int w_, int h_)
{
w = w_; h = h_;
totalNumber++; //有對象生成則增加總數
totalArea += w * h; //有對象生成則增加總面積
}
CRectangle::CRectangle(CRectangle & r)
{
totalNumber++;
totalArea += r.w * r.h;
w = r.w; h = r.h;
}
CRectangle::~CRectangle()
{
totalNumber--; //有對象消亡則減少總數
totalArea -= w * h; //有對象消亡則減少總而積
}
void CRectangle::PrintCRectangle()
{
cout << this->totalNumber << "," << this->totalArea << endl;
totalArea += this->w * this->h;
totalNumber++;
}
void CRectangle::PrintTotal(CRectangle a)
{
totalArea -= a.w * a.h;
totalNumber--;
/*cout << totalNumber << "," << totalArea << endl;*/
a.PrintCRectangle();
}
//必須在定義類的文件中對靜態成員變數進行一次聲明 //或初始化,否則編譯能通過,鏈接不能通過
int CRectangle::totalNumber = 0;
int CRectangle::totalArea = 0;
int main()
{
CRectangle r1(1, 1);
CRectangle *r2 = new CRectangle(2, 2);
CRectangle r3(r1);
//cout << CRectangle::totalNumber; //錯誤,totalNumber 是私有
CRectangle::PrintTotal(r1);
r2->PrintTotal(*r2);
r3.PrintTotal(r3);
delete r2;
CRectangle::PrintTotal(r1);
r1.PrintTotal(r3);
r3.PrintTotal(r3);
return 0;
}
上述代碼還可以改成:
void CRectangle::PrintCRectangle()
{
cout << this->totalNumber << "," << this->totalArea << endl;
//totalArea += this->w * this->h;
//totalNumber++;
}
void CRectangle::PrintTotal(CRectangle a)
{
totalArea -= a.w * a.h;
totalNumber--;
/*cout << totalNumber << "," << totalArea << endl;*/
a.PrintCRectangle();
totalArea += a.w * a.h;
totalNumber++;
}
即,只在PrintTotal函數中處理面積和計數的變化。
如果上面程序中將拷貝構造函數去掉,則結果會出錯。