標籤:

C++中類B需要訪問類A的私有成員變數,除了將B聲明為A的友元類外還有其它方法嗎?

1.類B與類A沒有繼承關係

2.不想在類A中添加公有的set/get函數,這樣的話其它類也能訪問這些成員變數了

請賜教


沒有。

如果你用樓下的各種奇招的話,坐等開除


// 喂喂我只是在開玩笑啊= =

#define private public

#include &

#undef private


很明顯出現這類需求就說明設計已經很有問題了,建議還是重新審視一下各個類的關係。


要不要用和能不能是兩回事

class A
{
public:
int x;
private:
int y;
};

int main(int argc, char* argv[])
{
A a;
//a.x = 1;
//a.y = 1; error
int* p = (int*)a;
*p = 1; //a.x = 1
*(p + 1) = 1; //a.y = 1
return 0;
}

私有變數也只是在編譯時不能被非友元類訪問

用地址訪問就好了

不過比較麻煩,也容易出問題

在有虛函數的時候還需要考慮虛表的大小

所以還是用友元類吧


按照偏移量計算並不是個好辦法,假如類的成員有不同的數據類型,那麼必然會有問題

所以稍微比較正常的方法是重新定義一個類,所有成員都和前一個一樣,不過訪問許可權都是public

再把指針reinterpret_cast一下就好

這種方法只要這兩個類在相同的模塊,使用相同的編譯器、相同的編譯選項進行編譯,一般是不會有問題的

class A
{
public:
A():m_x(0), m_y(2.0){}
private:
int m_x;
double m_y;
};

class PA
{
public:
A():m_x(0), m_y(2.0){}
int m_x;
double m_y;
};

然後

A *p1 = new A;
PA * p2 = reinterpret_cast&(p1);
p2-&>m_y;

但是這個方法依然很二逼,因為這個問題本來就很扯淡

屋子有門,我可以教你怎麼砸牆,但是牆塌了你被埋了不是我的事


計算好偏移量直接取,出了問題別找我。

class A{
private:
int m_xxx;
int m_yyy;
};
class B{
public:
void doSomething(A a){
(*((int*)(a))) = 123; // a.m_xxx = 123;
(*((int*)(a) + 1)) = 312; // a.m_yyy = 312;
}
};

因為很重要所以再強調一下,這樣做挺麻煩的,如果出了問題(比如被其他閱讀到這段代碼的人揍了、出現了莫名其妙的bug、偏移量算錯了、目標平台很獵奇……)別找我。

對了,這裡還有一種-不那麼容易被噴-腦洞大開的寫法,他可以讓你被噴的幾率減少0.000001%(我猜的):

class A{
private:
int m_xxx;
int m_yyy;
};
struct C{
int m_xxx;
int m_yyy;
};
class B{
public:
void doSomething(A a){
reinterpret_cast&(a)-&>m_xxx = 1;
reinterpret_cast&(a)-&>m_yyy = 2;
}
};


如果有虛函數,地址偏移貌似就不靈了吧,對不同的編譯器虛函數表指針的存放順序應該是不同的。


public:

setxxx(); //class yyy only


寫個帶審查的set,get。

傳入一個介面作為憑證。


類A寫一個公有函數把私有成員提供或賦值,然後調用類A函數


nested class


紙上談兵的方法是,讓類的一個公共成員函數返回這個類的一個私有數據成員的引用(引自Visual C++ 2008大學教程 第二版 P418

)。


既然是私有變數,就是不想讓其它類訪問,這是C++中對類的私有變數的定義。

你現在已經有需求訪問A的私有變數了,正確方法是:

  1. 把類A中的變數聲明為Public。
  2. 添加公有方法。

其它的方法都會對程序的可理解性、可維護性造成各種困擾,非正途。


linux kernel source 裡面有一個macro叫container_of,你可以參考一下裡面如何普遍地計算偏移量


所謂公有成員還是私有成員,這種訪問控制完全是編譯期的概念好不好!運行態時不受任何控制,只要你知道它在哪兒(也就是地址)


調用類a的公共方法,以類組合的形式編碼?新手求輕拍


推薦閱讀:

如何在#define里使用"#"?
繼承模板類為什麼可以用this訪問基類?
c++模板類拷貝構造函數的問題,有點疑惑?
std::move(expr)和std::forward(expr)參數推導的疑問?
C++ delete[] 是如何知道數組大小的?

TAG:編程語言 | C | CC |