何の話か
C++ 初心者です.
実際にそういうことをしたい場面があるわけではないんだけど,何故か以下のようなことをふと考えた.だけ.
class X を Y の friend にすると,X から Y の全てを触れる.
→ この「全て」ってのが嫌な場合にはどうする? っていう.
例えばこんな↓場合,どうすればいいかな? と.
class Y
{
friend class X;
private:
//コレはXに触らせたいが…
void PrivateFunc1(){ std::cout << "PF1\n"; }
//以下はXにも触らせたくない
void PrivateFunc2(){ std::cout << "PF2\n"; }
int m_Val = 77;
};
(1)Yを2分割
そんなことのために継承とか,何か嫌だな.
//Xがfirendな部分だけのclassを作って…
class IF_for_X
{
friend class X;
protected:
void PrivateFunc1(){ std::cout << "PF1\n"; }
};
//↑を継承する
class Y : public IF_for_X
{
private:
void PrivateFunc2(){ std::cout << "PF2\n"; }
int m_Val = 77;
};
(2)三店方式
直に friend にするのではなく,X と Y の間に1つそれ用のを噛ませる.
class Y
{
public:
class IF_for_X
{
friend class X;
static void PrivateFunc1( Y &y ){ y.PrivateFunc1(); }
};
private:
void PrivateFunc1(){ std::cout << "PF1\n"; }
void PrivateFunc2(){ std::cout << "PF2\n"; }
int m_Val = 77;
};
class X
{
public:
void Test( Y &y ){ Y::IF_for_X::PrivateFunc1( y ); }
};
(3)Xにしか作れないものを要求
public だけども実質 X からしか使えないでしょ,っていう.
class Permit
{//Xにしか作れない
friend class X;
Permit(){}
};
class Y
{
public:
//Xにしか作れないものを引数にした public なメンバ関数を用意する
void PF1( const Permit & ){ PrivateFunc1(); }
private:
void PrivateFunc1(){ std::cout << "PF1\n"; }
void PrivateFunc2(){ std::cout << "PF2\n"; }
int m_Val = 77;
};
class X
{
public:
void Test( Y &y ){ y.PF1( Permit{} ); }
void Test2( Y &y ){ y.PF1( {} ); } //{}とだけ書くのでもいける模様
};
……とかいうのを実験してたところ,↑の Permit のコンストラクタを
Permit() = default;
って書いたら,
int main()
{
Permit p; //エラー:アクセスできません
Permit *p = new Permit(); //エラー:アクセスできません
Permit p{}; // Permit の ctor を =default とすると通ってしまう?
}
という結果になって困惑中.Why?