我有以下情况:
namespace MyFramework {
class A {
void some_function_I_want_B_to_use() {}
};
class B {
B() {
some_function_I_want_B_to_use() {}
}
};
}
我希望some_function_I_want_B_to_use
在MyFramework
命名空间之外不可见,但我确实希望MyFramework中的任何人都可以看到它(或者,只有B类可见也可以)。我有很多像这样的方法,是将它们隐藏在MyFramework的公共API中以便在MyFramework
朋友中制作所有类的唯一方法吗?我也在考虑将所有“低级”类放在B中,但是我不想沿着这条路走下去,直到我确信它能够完成从B内部访问所有A方法的能力,但不是在MyFramework之外。
重申一下,我有一个框架,它都是在一个名称空间内创建的,每个类都有对使用框架的一般公众有用的方法。但是,每个类还有一些方法使公共API复杂化,但框架才能正常运行。
答案 0 :(得分:3)
我希望
some_function_I_want_B_to_use
在MyFramework
命名空间之外不可见,但我确实希望MyFramework
内的所有人都可以看到它。
总之,您需要类似于Java中的包。
对您而言,对于名称空间来说, 是不可能的。命名空间中包含的每个类都可以从命名空间的外部访问:命名空间是开放的。
解决方案通常是为实现细节添加另一个命名空间:
namespace MyFramework
{
// Implementation details
// Should not be used by the user
namespace detail
{
class A
{
public:
void func();
};
}
class B
{
public:
B()
{
A a;
a.func();
}
};
}
不要忘记添加注释,说明用户不会使用detail
命名空间。
答案 1 :(得分:2)
共同惯例,例如在Boost中,是一个名为detail
的嵌套命名空间。
如果您希望强制可访问性,您可以始终使用名为class
的嵌套detail
。该类提供可访问性检查,但缺乏像命名空间一样的可扩展性。但是,detail
范围很少需要扩展。
所以,它的丑陋,
namespace my_framework {
class detail
{
private:
static void some_function_I_want_B_to_use() {}
public:
class A
{};
class B
{
B() { some_function_I_want_B_to_use(); }
};
};
typedef detail::A A; // "using detail::A"
typedef detail::B B; // "using detail::B"
} // namespace my_framework
顺便说一下,注意B类(直接来自问题)有一个私有默认构造函数,因此不能创建它的实例。
答案 2 :(得分:2)
Pimpl idiom,经常被称为编译防火墙,是您正在寻找的。整个Qt是使用这个习惯用法实现的。
// A.hpp
namespace MyFramework {
class A {
private:
class Private;
Private* implementation;
};
}
// A_Private.hpp
#include "A.hpp"
namespace MyFramework {
class A::Private {
public:
void some_function_I_want_B_to_use() {}
};
}
// A.cpp
#include "A_Private.hpp"
namespace MyFramework {
A::A() {
implementation->some_function_I_want_B_to_use();
}
}
// B.hpp
#include "A.hpp"
namespace MyFramework {
class B {
B();
A a;
};
}
// B.cpp
#include "A_Private.hpp"
namespace MyFramework {
B::B() {
a.implementation->some_function_I_want_B_to_use();
}
}
注意:当然A_Private.hpp
不会进入您框架最终分发的include
目录,即它仍然是包私有需要。
这个例子很基础。当然,它可以更先进和更强大。此外, Pimpl 还有很多其他优点。有关所有这些信息,请参阅: