jav*_*ver 8 c++ class-visibility visual-studio-2015
有没有办法伪造它?
是否有任何可以模拟最接近行为的C++宏/模板/魔术?
Util.h (图书馆)
class Util{
//note: by design, this Util is useful only for B and C
//Other classes should not even see "Util"
public: static void calculate(); //implementation in Util.cpp
};
Run Code Online (Sandbox Code Playgroud)
Bh (图书馆)
#include "Util.h"
class B{ /* ... complex thing */ };
Run Code Online (Sandbox Code Playgroud)
Ch (图书馆)
#include "Util.h"
class C{ /* ... complex thing */ };
Run Code Online (Sandbox Code Playgroud)
Dh (用户)
#include "B.h" //<--- Purpose of #include is to access "B", but not "Util"
class D{
public: static void a(){
Util::calculate(); //<--- should compile error
//When ctrl+space, I should not see "Util" as a choice.
}
};
Run Code Online (Sandbox Code Playgroud)
让所有成员Util都是私人的,然后声明: -
friend class B;
friend class C;
Run Code Online (Sandbox Code Playgroud)
(编辑:感谢ASH "此处不需要前瞻声明".)
坏处 :-
Util以某种方式识别B和C.Util,打破任何private访问控制.D只是不能使用Util,但仍然可以看到它.Util在使用自动完成(例如ctrl+space)时仍然是一个选择D.h. (编辑)注:编码方便; 防止一些错误或错误的使用/更好的自动完成/更好的封装.这不是反黑客攻击,也不是防止未经授权访问该功能.
(编辑,接受):
可悲的是,我只能接受一种解决方案,因此我主观地选择了需要较少工作并提供很大灵活性的解决方案.
对于未来的读者来说,Preet Kukreti(和评论中的texasbruce)和Shmuel H.(以及ASH评论)也提供了值得一读的好解决方案.
我认为最好的办法就是不要Util.h在公共标题中加入.
为此,#include "Util.h"仅在实现cpp文件中:
Lib.cpp:
#include "Util.h"
void A::publicFunction()
{
Util::calculate();
}
Run Code Online (Sandbox Code Playgroud)
通过这样做,您可以确保更改Util.h只会在库文件中产生影响,而不会在库的用户中产生影响.
这种方法的问题是无法Util在您的公共标头(A.h,B.h)中使用.前向声明可能是此问题的部分解决方案:
// Forward declare Util:
class Util;
class A {
private:
// OK;
Util *mUtil;
// ill-formed: Util is an incomplete type
Util mUtil;
}
Run Code Online (Sandbox Code Playgroud)
一种可能的解决方案是将其推Util入名称空间,并将typedef其放在B和C类中:
namespace util_namespace {
class Util{
public:
static void calculate(); //implementation in Util.cpp
};
};
class B {
typedef util_namespace::Util Util;
public:
void foo()
{
Util::calculate(); // Works
}
};
class C {
typedef util_namespace::Util Util;
public:
void foo()
{
Util::calculate(); // Works
}
};
class D {
public:
void foo()
{
Util::calculate(); // This will fail.
}
};
Run Code Online (Sandbox Code Playgroud)
如果该类Util是在 中实现的util.cpp,则需要将其包装在namespace util_namespace { ... }. 就B和C而言,它们的实现可以引用名为 的类Util,没有人会更明智。如果没有启用typedef,D将找不到该名称的类。
| 归档时间: |
|
| 查看次数: |
283 次 |
| 最近记录: |