靜態成員函數訪問非靜態成員
㈠ c++靜態成員函數訪問非靜態數據成員
沒有搞錯
這是C++語法所決定的
C++類的靜態成員變數和靜態成員函數是所有實例共用的
這個和C的靜態變數靜態函數的概念不一樣,需要理解
所以類靜態函數訪問非靜態變數只有通過參數指明要訪問的對象才可以
因為 i,j都是類對象當然可以訪問私有成員
外部不允許訪問私有成員是說類以外代碼不允許訪問
兩個類實例間的訪問也是在類內部完成的
void A::f(A a)
{
cout<<a.x;
}
這個本身是類的成員函數,當然可以訪問
因為函數 f本身是靜態函數,所以訪問時要指明具體訪問對象
這就在於正確理解
㈡ 靜態成員函數為什麼不能訪問本類中的非靜態成員
和靜態數據成員一樣,靜態成員函數是類的一部分,而不是對象的一部分。如果要在類外調用公用的靜態成員函數,要用類名和域運算符「∷」。如 Box∷volume( ); 實際上也允許通過對象名調用靜態成員函數,如 a.volume( ); 但這並不意味著此函數是屬於對象a的,而只是用a的類型而已。 靜態成員函數的作用是為了能處理靜態數據成員。 可以說,靜態成員函數與非靜態成員函數的根本區別是:非靜態成員函數有this指針,靜態成員函數並不屬於某一對象,它與任何對象都無關,靜態成員函數沒有this指針。由此決定了靜態成員函數不能訪問本類中的非靜態成員。 在C++程序中,靜態成員函數主要用來訪問靜態數據成員,而不訪問非靜態成員。假如在一個靜態成員函數中有以下語句: cout<<height<<endl; //若height已聲明為static,則引用本類中的靜態成員,合法 cout<<width<<endl; //若width是非靜態數據成員,不合法 但是,並不是絕對不能引用本類中的非靜態成員,只是不能進行默認訪問,因為無法知道應該去找哪個對象。如果一定要引用本類的非靜態成員,應該加對象名和成員運算符「.」。如 cout<<a.width<<endl; //引用本類對象a中的非靜態成員
㈢ c++ 靜態成員函數能調用非靜態成員嗎
靜態成員的定義是針對類的一個對象而言的,即該類的每個對象都有一套自己的靜態成員變數和函數。如果想要靜態成員函數調用非靜態成員,那就必須有一個這個類的instance(實例)才行,例如:
classfoo{
public:
foo()
:m_i(0)
{}
staticvoidadd1(foo&instance);//實例傳入函數
staticvoidadd1();//定義一個自身的靜態實例
private:
staticfoom_instance;
intm_i;
};
voidfoo::add1(foo&instance)
{
instance.m_i=instance.m_i+1;
}
voidfoo::add1()
{
m_instance.m_i=m_instance.m_i+1;
}
謝謝,望採納!
㈣ 靜態成員函數為什麼不可以調用非靜態成員函數
原因如下;
和靜態數據成員一樣,靜態成員函數是類的一部分,而不是對象的一部分。如果要在類外調用公用的靜態成員函數,要用類名和域運算符「∷」。
如 Box∷volume( ); 實際上也允許通過對象名調用靜態成員函數,如 a.volume( ); 但這並不意味著此函數是屬於對象a的,而只是用a的類型而已。 靜態成員函數的作用是為了能處理靜態數據成員。 可以說,靜態成員函數與非靜態成員函數的根本區別是:非靜態成員函數有this指針,靜態成員函數並不屬於某一對象,它與任何對象都無關,靜態成員函數沒有this指針。
由此決定了靜態成員函數不能訪問本類中的非靜態成員。 在C++程序中,靜態成員函數主要用來訪問靜態數據成員,而不訪問非靜態成員。假如在一個靜態成員函數中有以下語句: cout<<height<<endl; //若height已聲明為static,則引用本類中的靜態成員,合法 cout<<width<<endl; //若width是非靜態數據成員,不合法。但是,並不是絕對不能引用本類中的非靜態成員,只是不能進行默認訪問,因為無法知道應該去找哪個對象。如果一定要引用本類的非靜態成員,應該加對象名和成員運算符「.」。如 cout<<a.width<<endl; //引用本類對象a中的非靜態成員
㈤ 線程的靜態函數如何訪問類的非靜態成員函數或成員變數
靜態成員函數不能訪問非靜態成員變數,這是規定。
但是你可以換下解決問題的思路。線程的入口函數除了可以鎖靜態成員函數,也可是全局函數。
在全局函數里獲取主窗口的句柄之後,接下來可以訪問各種成員變數。
㈥ 靜態成員函數怎麼引用該類中的非靜態成員函數
最佳答案,感覺有些沒說明白,是說靜態成員函數調用了原類的普通成員函數拷貝構造函數和析構函數么?修改了下代碼,大致可以看清:
#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函數中處理面積和計數的變化。
如果上面程序中將拷貝構造函數去掉,則結果會出錯。
㈦ 靜態成員函數可以訪問非靜態成員變數嗎
靜態成員函數不能訪問非靜態成員變數,這是規定。 但是你可以換下解決問題的思路。線程的入口函數除了可以鎖靜態成員函數,也可是全局函數。 在全局函數里獲取主窗口的句柄之後,接下來可以訪問各種成員變數。
㈧ 靜態成員函數是不是絕對不能訪問本類中的非靜態成員
是,因為編譯器做不到。靜態成員在非靜態成員之前初始化。
㈨ 怎樣讓靜態成員函數訪問非靜態成員變數
靜態成員函數不能訪問非靜態成員變數,這是規定。 但是你可以換下解決問題的思路。線程的入口函數除了可以鎖靜態成員函數,也可是全局函數。 在全局函數里獲取主窗口的句柄之後,接下來可以訪問各種成員變數。
希望對你有幫助。