与朋友声明相反

时间:2018-10-19 12:52:59

标签: c++ c++17 friend

假设我们有一个带有私有构造函数的类,通过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私有并为所有班级添加朋友?

4 个答案:

答案 0 :(得分:8)

这种东西不存在,这将是毫无意义的。假设您遇到这样的情况:

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的成员(它是全局函数),因此它不是敌人。因此,可以轻松地规避这种不友好。

答案 1 :(得分:1)

这不可能真的完成,但是也许对您来说足够了:

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.
    }
};

答案 2 :(得分:0)

C ++中没有这样的概念。

公共属性将始终是公共属性,但是您可以通过使构造函数受到保护(例如,仅对选定的类可见)来限制Foo的显示(尽管建议限制friend)。也许也将Foo设为Bar2的受保护类,因为只有Bar2或其子代会实际使用它。

答案 3 :(得分:0)

正如其他人已经说过的那样,您的愿望打破了封装的想法,因为您无法始终知道敌人是谁。

但是,仍然有可能(几乎)获得您想要的东西:

<!DOCTYPE html>
<html>
<head>
	<title>Browser detector</title>

</head>
<body onload="myFunction()">
// your code here 
</body>
</html>