c++ - 如何对除 T 级以外的所有人隐藏数据

标签 c++ templates friend information-hiding access-protection

我想要一个 A 类型,它将其隐藏的数据提供给类型 T 的对象,但对其他人隐藏数据。我的 C++ 编译器恰好是 GCC 4.4,但这应该无关紧要。为什么这行不通?

#include <iostream>

template <class T> class A {
  private:
    int n1;
  public:
    friend class T;
    A(const int n0 = 0) : n1(n0) {}
};

class B {
  public:
    int f(const A<B> a) const { return a.n1; }
    B() {}
};

int main() {
    const A<B> a(5);
    const B b;
    const int m = b.f(a);
    std::cout << m << "\n";
    return 0;
}

顺便说一句,这工作正常,除了它无法隐藏数据:

#include <iostream>

template <class T> class A {
  private:
    int n1;
  public:
    int n() const { return n1; }
    A(const int n0 = 0) : n1(n0) {}
};

class B {
  public:
    int f(const A<B> a) const { return a.n(); }
    B() {}
};

int main() {
    const A<B> a(5);
    const B b;
    const int m = b.f(a);
    std::cout << m << "\n";
    return 0;
}

难道C++真的不允许在编译时将友元类指定为模板参数吗?为什么不?如果不是,那么我应该使用什么替代技术来隐藏数据? (如果可能的话,人们更喜欢编译时技术。)

请问我这里有什么误会?

(我看到了相关问题的一些答案 herehere, 但他们要么没有回答我的特定问题,要么我不明白他们回答了。无论如何,也许我完全使用了错误的技术. 虽然我仍然对为什么 friend 类 T 失败很感兴趣,但我真正想知道的是如何隐藏数据,无论是通过 friend 还是通过其他方式。)

谢谢。

最佳答案

您的编译器太旧了。 C++11 允许您将模板参数声明为友元。

§11.3 [class.friend] p3

A friend declaration that does not declare a function shall have one of the following forms:

  • friend elaborated-type-specifier ;
  • friend simple-type-specifier ;
  • friend typename-specifier ;

If the type specifier in a friend declaration designates a (possibly cv-qualified) class type, that class is declared as a friend; otherwise, the friend declaration is ignored.

它甚至包含一个模板参数的例子作为 friend :

class C;
// [...]
template <typename T> class R {
  friend T;
};

R<C> rc;   // class C is a friend of R<C>
R<int> ri; // OK: "friend int;" is ignored

遗憾的是,C++03 没有办法做到这一点,但是您可以简单地将一个自由函数作为 friend ,让它充当从一个类获取数据并将其传递给另一个类的“胶水”代码。另一种方式可能是 passkey pattern .

关于c++ - 如何对除 T 级以外的所有人隐藏数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9754084/

相关文章:

c++ - Friend c++ 不与私有(private)成员一起工作

c++ - 使类模板成为其自身的 friend 以进行不同的实例化

c++ - 恢复磁盘支持哪个 Windows 子系统

c++ - 从 bool vector 返回索引的 int 函数

c++ - C++-将std::exp应用于std::vector

c++ - 返回对原始参数的引用

python - Django:刚开始学django 应该用django 还是jinja2 模板

C++ 模板化友元类

c++ - InetPton() 将任何 IP 转换为 1.0.0.0

c++ - "Member is private"虽然我不从外部访问它,但在使用尾随返回类型时