C++クラスのフレンド関数、フレンドクラス、フレンドメンバー関数について学習しています。 は今、次のコードは、罰金コンパイル:C++フレンドクラスとフレンドメンバー関数
#include <iostream>
class A
{
public:
friend class B;
//friend void B::set(int i);
//friend int B::get();
friend int function(A a);
A(int i);
void set(int i);
int get();
private:
int i;
};
A::A(int i) : i(i)
{
}
void A::set(int i)
{
this->i = i;
}
int A::get()
{
return i;
}
class B
{
public:
B(A a);
void set(int i);
int get();
private:
A a;
};
B::B(A a) : a(a)
{
}
void B::set(int i)
{
a.i = i;
}
int B::get()
{
return a.i;
}
int function(A a);
int main(int argc, char *argv[])
{
A a(0);
std::cout << "in A i=" << a.get() << std::endl;
a.set(10);
std::cout << "in A i=" << a.get() << std::endl;
B b(a);
std::cout << "in B i=" << b.get() << std::endl;
b.set(21);
std::cout << "in B i=" << b.get() << std::endl;
std::cout << "function returns " << function(a) << std::endl;
}
int function(A a)
{
return a.i;
}
私は前方クラスB、または機能「機能」を宣言しなくてもクラスAに「機能」をクラスBに友情を付与すると機能するようにできています。今 、私はクラスBに2つのメンバ関数への友情を付与したい場合、私はクラスAを定義する前に、クラスBを定義しない場合、それは動作しません:
#include <iostream>
class B; // doesn't work, incomplete type (complete type needed)
class A
{
public:
//friend class B;
friend void B::set(int i);
friend int B::get();
friend int function(A a);
A(int i);
void set(int i);
int get();
private:
int i;
};
A::A(int i) : i(i)
{
}
void A::set(int i)
{
this->i = i;
}
int A::get()
{
return i;
}
B::B(A a) : a(a)
{
}
void B::set(int i)
{
a.i = i;
}
int B::get()
{
return a.i;
}
int function(A a);
int main(int argc, char *argv[])
{
A a(0);
std::cout << "in A i=" << a.get() << std::endl;
a.set(10);
std::cout << "in A i=" << a.get() << std::endl;
B b(a);
std::cout << "in B i=" << b.get() << std::endl;
b.set(21);
std::cout << "in B i=" << b.get() << std::endl;
std::cout << "function returns " << function(a) << std::endl;
}
int function(A a)
{
return a.i;
}
が、私は、クラスBを定義することはできませんクラスAを定義する前に私は立ち往生しています。前方宣言(定義していない)はクラスBも動作しません。
だから私の質問は以下のとおりです。
1)私は友情宣言で関数やクラス全体を宣言転送する必要がありますが、私はそのクラスのメンバ関数を指定する必要がある場合、私はクラスを定義する必要がありますいけない理由? 私は、友情宣言は常識的な宣言ではないことを知っています(彼らは単にアクセス権を与え、何も宣言しません)。
2)私のコードをコンパイルするにはどうしたらいいですか?(AのメンバーオブジェクトをA *として宣言する以外に)
実際、クラスAはパブリックインターフェイスを持っているため、クラスBのメンバー関数をフレンド関数として宣言する必要はありません。 –
@ VladfromMoscowそれは確かに人為的な例です。私はちょうどそれがうまくいかないと私はそれを回避することができます理解したい。 – Luca
"クラスAを定義する前にクラスBを定義できません"なぜですか? –