与朋友声明相反
Opposite of friend declaration
假设我们有一个具有私有构造函数的类,通过friend
我们可以允许一些特定的类仍然创建此类的对象:
class Foo
{
friend class Bar;
private:
Foo();
};
class Bar
{
Bar()
{
//create a Foo object
}
};
现在,如果我想要与friend
相反,Foo
看起来像这样:
class Foo
{
//enemy/foe??? class Bar; (if only)
public:
Foo();
};
然后没有Bar
方法可以访问Foo
构造函数/创建Foo
的对象,但其他类可以访问(因为它是public
(。
class Bar
{
Bar()
{
Foo foo; //compiler error
}
};
这样的结构是否可行,还是我坚持保持Foo
私密并为所有课程添加朋友?
这样的事情是不存在的,而且是极其没有意义的。想象一下,您遇到这样的情况:
class Foo
{
enemy class Bar;
public:
Foo() {}
};
class Bar
{
void evil() { Foo{}; }
};
没有什么能阻止Bar
的实现者这样做:
class Bar
{
void evil() { do_evil(*this); }
};
void do_evil(Bar &self)
{
Foo{};
}
do_evil
不是Bar
的成员(它是一个全局函数(,所以它不是敌人。因此,这种不友好可以轻而易举地规避。
这真的做不到,但也许以下对你来说就足够了:
template <typename T> struct Tag {};
class Foo
{
public:
template <typename T>
Foo(Tag<T>) {}
Foo(Tag<Bar>) = delete;
// ...
};
因此要求"创造者"识别"自己。
class Bar
{
Bar()
{
Foo foo{Tag<Bar>{}}; //compiler error
// Foo foo{Tag<void>{}}; // valid as we can cheat about identity.
}
};
C++中没有这样的概念。
公共属性将始终是公共的,但您可以通过保护构造函数来限制Foo
的公开,例如,并且仅对选定的类可见(尽管建议限制friend
(。也许也可以Foo
作为受保护的Bar2
类,因为只有Bar2
或其子代才会真正使用它。
正如其他人已经说过的那样,你的欲望打破了封装的想法,因为你不可能总是知道你的敌人是谁。
但是,仍然有可能得到(几乎(你想要的:
#include <type_traits>
struct enemy; // We need a forward declaration of your enemy
struct my_class {
// The access is done using a factory, where the caller has to tell
// us his own name
template <class T>
struct make{
static_assert(!std::is_same<T,enemy>::value,"you are my enemy.");
friend T;
private:
my_class operator() () { return my_class{}; }
};
private:
my_class(); // This is the constructor we care about
};
struct no_enemy {
void bar() {
my_class a = my_class::make<no_enemy>{}(); // works
}
};
struct enemy {
void bar() {
my_class b = my_class::make<enemy>{}(); // error: static_assert failed
my_class c = my_class::make<no_enemy>{}(); // error: foo is "private"
}
};
相关文章:
- 与朋友声明相反
- 为什么即使我声明了朋友类,我也会收到错误"无法访问类中声明的私人成员"
- 为什么C++需要公共继承,忽略朋友声明,才能使动态向下工作?
- 朋友声明的复杂范围界定规则有什么意义?
- 警告定义朋友操作员在名称空间内声明
- 朋友功能声明中的错误C
- 类与朋友而不是前向声明,:哪个编译器是正确的
- Forward宣布了Singleton班级,并带有Freshial声明的朋友功能
- 在模板类中编写朋友函数声明的正确方法是什么?
- 朋友功能声明为会员函数
- 如何在两个类之外的模板类内部的非模板类中声明的朋友函数定义
- 声明一个简单模板类的variadic模板类的朋友
- 可以在C 11中有条件声明的朋友类
- 可以在C 03中有条件地声明朋友类吗?
- 正确声明模板化运算符<<(basic_ostream< charT、特征>、myClass<T > ) 作为朋友
- 朋友向成员操作员*的模板运营商*声明*
- 如何在模板类中声明特定于类型的模板朋友函数
- 我们如何在 c++ 中以朋友声明"friend elaborated-class-name ;"为例?
- 显式专用化不能是朋友声明
- 我可以在Visual Studio 2012中将方法声明为朋友吗?