2017-08-30 63 views
2

我有一個類聲明一些靜態變量:A類由另一個類訪問僅

#include <iostream> 
class A 
{ 
private: 
static int x; 
public: 
static int y; 
static getX(){ return A::x;} 
static setX(int z){ A::x = z;} 
}; 

int A::x = 0; 
int A::y = 0; 

現在,A類可以被任何人/任何地方,它的成員變量可以被操縱進行訪問。我如何只允許另一個可以訪問類A靜態變量/方法的類?

class B 
{ 
public: 
void showX(){A::setX(9) ; std::cout << A::getX() << std::endl;} 
void showY(){A::y = 8; std::cout << A::y << std::endl;} 
}; 

int main() 
{ 
B b1; 
b1.showX(); 
b1.showY(); 
} 
+0

閱讀'私人'和'朋友'。 –

回答

4

B定義爲A私有類。

#include <iostream> 

class B 
{ 
    class A 
    { 
    private: 
     static int x; 
    public: 
     static int y; 
     static int getX() { 
      return A::x; 
     } 
     static void setX(int z) { 
      A::x = z; 
     } 
    }; 

public: 
    void showX() { 
     A::setX(9) ; 
     std::cout << A::getX() << std::endl; 
    } 
    void showY() { 
     A::y = 8; 
     std::cout << A::y << std::endl; 
    } 
}; 

int B::A::x = 0; 
int B::A::y = 0; 

int main() 
{ 
    B b1; 
    b1.showX(); 
    b1.showY(); 
} 
+0

B的析構函數是否也會調用A的析構函數 - 這是我目前不希望發生的事情? – Prakash

+0

沒有構造A的實例 - 因此不會調用任何析構函數 –

+0

謝謝 - 澄清一下 - 因此,當調用B析構函數時 - 類A靜態變量將仍然存在於內存中並且不會被銷燬 - 換句話說,它們將被銷燬只有當程序終止? – Prakash

3

如果類應該只在一個其他類已知的,那麼我會說這應該是類

class B 
{ 
private: 
    class A 
    { 
    private: 
     static int x; 
    public: 
     static int y; 
     static int getX(){ return A::x;} 
     static void setX(int z){ A::x = z;} 
    }; 

public: 
    void showX(){A::setX(9) ; std::cout << A::getX() << std::endl;} 
    void showY(){A::y = 8; std::cout << A::y << std::endl;} 
}; 

int B::A::x = 0; 
int B::A::y = 0; 

int main() 
{ 
    B b1; 
    b1.showX(); 
    b1.showY(); 
} 

現在的私人實現細節的A存在不除B之外的任何人都知道。

+0

B的析構函數是否也會調用A的析構函數 - 這是我目前不希望發生的事情? – Prakash

+0

不,它不會,因爲'B'沒有'A'成員,它僅僅是定義的範圍。 – CoryKramer

+0

感謝 - 一個澄清 - 所以當調用B析構函數時 - 類A靜態變量仍然存在在內存中並且不會被銷燬 - 換句話說,只有當程序終止時它們纔會被銷燬? – Prakash

2

CRTP可以讓你做到這一點沒有觸及B:

class B; 

template<class A> 
class A_shared_with_B { 
private: 
    static int y; 
    static int getX(){ return A::x;} 
    static void setX(int z){ A::x = z;} 
    friend class B; 
}; 

class A:public A_shared_with_B<A> { 
    friend class A_shared_with_B<A>; 
private: 
    static int x; 
}; 

現在B訪問的A_shared_with_Bprivate內容,A_shared_with_B訪問的Aprivate內容,B不必直接訪問private內容A

如果你願意修改B和重命名ABprivate段內命名A使名稱很難從外面B,這類似於上述的訪問控制達到。一個很好的優勢,這種技術就是可以通過傳遞A原本無用的情況下向外部template功能授予A代理訪問:

template<class A> 
void has_proxy_A_access(A) { 
    std::cout << A::getX(); 
} 

其中B情況下可以撥打has_proxy_A_access(A{})並授予使用A到權利一個給定的(模板)函數。

0

已經有答案顯示如何使A成爲一個內部類。爲了完整這裏的目的是private + friend溶液(由尼爾·巴特沃思評論已提出):

#include <iostream> 
class A { 
private: 
    friend class B; 
    static int x; 
    static int y; 
    static getX(){ return A::x;} 
    static setX(int z){ A::x = z;} 
}; 

一個friend訪問類的所有成員,這樣就可以使A私人所有成員並且只允許B訪問它們,使它成爲朋友。