我正在用C ++编写一个库。我的库中有两个类,A
和B
。我想隐藏任何引用我的库的代码中的A()
构造函数。我还希望课程B
能够调用A()
构造函数。
我来自C#背景,并且很少记住我的C ++。在C#中,我只是将A()
构造函数声明为internal
。我已经读过,在C ++中最接近的方法是friend
声明和前向声明的组合。我该怎么做呢?以下是我的三个文件:
A.H:
#pragma once
class A
{
private:
A();
};
B.h
#pragma once
class A;
class B
{
public:
A createA();
};
B.cpp:
#include "A.h"
#include "B.h"
A B::createA()
{
A result; //cannot access private member declare in class 'A'
return result;
}
我已经尝试将其添加到A.h:
public: friend A createA();
我试图将此添加到A.h,并附带相应的前瞻声明:
public: friend A B::createA();
我反而尝试向A.h添加extern class B;
并使B成为这样的类:
public: friend class B;
我很茫然。
我认为如果我让B::createA()
函数直接返回指向A
对象而不是A
对象的指针,这可能会更容易,但在我的情况下不会这样做。我正在模拟一个封闭的API,API调用返回一个A
对象而不是一个指针。
答案 0 :(得分:3)
您可能只需要从第三次尝试中删除“extern”,将其转换为正确的前向声明。尝试:
A.H:
#pragma once
class B;
class A
{
friend class B;
private:
A();
};
答案 1 :(得分:1)
除非绝对必要,否则您应该A
构建自己(或者拥有一个创建A
的工厂)。如果您真的希望B
这样做:
class B; // foward declared
class A
{
private:
A() {}
friend class B;
};
class B
{
public:
A CreateA()
{
A a;
return a;
}
};
int main()
{
B b;
A a = b.CreateA();
return 0;
}
注意:在B
中声明为friend
之前,您必须转发声明A
。
如果您只想将此功能作为朋友:
class A;
class B
{
public:
A CreateA();
};
class A
{
private:
A() {}
friend class A B::CreateA();
};
A B::CreateA()
{
A a;
return a;
}
int main()
{
B b;
A a = b.CreateA();
return 0;
}
答案 2 :(得分:1)
您不需要external
关键字。简单说明:
// In A.h
class B; // Forward declaration
class A
{
friend class B; // Make all the class B friend
A();
};
// In B.h
class B
{
public:
A createA() {}
};
答案 3 :(得分:0)
你可以让B成为A的朋友:
class A
{
private:
A();
friend class B;
};