2012-04-23 184 views
2

我知道你可以用繼承來做到這一點,但是你打算使用繼承,除了'是'的情況。我也知道有朋友,但他們也允許私人成員訪問。C++:允許訪問受保護的類的成員,而不是私人成員

有沒有這樣做的方法(允許訪問受保護的類的成員而不是私人成員)?

要重新說明問題,我有第1課和第2課。我希望第2課有權訪問第1課的受保護和公開成員,但不是私人成員。我將如何做到這一點?

+0

這是什麼'你'這個'你在'有什麼辦法嗎?' – 2012-04-23 08:31:32

+0

允許訪問誰? – 2012-04-23 08:32:10

+0

我應該更清楚。我指的是這樣一個問題:「允許訪問受保護的成員而不是私人成員」 – Jalfor 2012-04-23 08:32:40

回答

4

這是不優雅,但是這可能爲你工作:

class B; 

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

class A_wrapper : public A { 
    friend B; 
}; 


class B { 
public: 
    A_wrapper a; 
    int foo() { 
     a.x; // Ok 
     a.y; // Compiler error! 
    } 
}; 
+0

有趣的解決方案:)即使我認爲user986993有設計問題... – 2012-04-23 08:50:30

+0

確實很難得到一些乾淨的東西。 'protected'在基類子對象的成員上工作,但不在同一類型的其他對象的成員上工作。 (也就是隻能通過'this') – MSalters 2012-04-23 08:52:08

+0

@OliCharlesworth,但你會說這樣做是個好主意嗎?不是你的實現,而是總體想法。 – juanchopanza 2012-04-23 09:00:39

0

奧利的提供了更緊密的解決方案(+1),但你也可以使用選擇性的朋友來解決:

#include <iostream> 

class t_thing; 

class t_elsewhere { 
public: 
    void print(const t_thing& thing); 
}; 

class t_thing { 
public: 
    class t_selective_friend { 
     static int Prot(const t_thing& thing) { 
      return thing.prot; 
     } 

     friend class t_elsewhere; 
    }; 
public: 
    int publ; 
protected: 
    int prot; 
protected: 
    int priv; 
}; 

void t_elsewhere::print(const t_thing& thing) { 
    std::cout << t_thing::t_selective_friend::Prot(thing) << std::endl; 
} 

int main() { 
    t_thing thing; 

    thing.publ; /* << ok */ 
    thing.prot; /* << error */ 
    thing.priv; /* << error */ 
    t_elsewhere().print(thing); /* << ok */ 
    return 0; 
} 

有時候這種冗長/控制很好......

0

很久以前,在這個網站上,我提出了一個使用Key的方案。這個想法是,主類記錄了接口的哪些部分可以公開訪問,哪些需要密鑰,然後將密鑰的友誼授予需要它的人。

class Key { friend class Stranger; Key() {} ~Key() {} }; 

class Item { 
public: 
    void everyone(); 

    void restricted(Key); 
private: 
}; 

現在,只有Stranger可以使用restricted方法,因爲在這裏證明:

class Stranger { 
public: 
    void test(Item& i) { 
     Key k; 
     i.restricted(k); 
    } 

    Key key() { return Key(); } 

    Key _key; 
}; 

class Other { 
    void test(Item& i) { 
     Stranger s; 
     i.restricted(s.key()); // error: ‘Key::~Key()’ is private 
           // error: within this context 
    } 

    void test2(Item& i) { 
     Stranger s; 
     i.restricted(s._key); // error: ‘Key::~Key()’ is private 
           // error: within this context 
           // error: initializing argument 1 of ‘void Item::restricted(Key)’ 
    } 
}; 

這是一個非常簡單的方案,它允許一個更細粒度的辦法,充分友誼。