将友元的引用成员初始化为类私有成员

Initializing a friend's reference member to a class private member

本文关键字:成员 初始化 引用 友元      更新时间:2023-10-16

我想初始化一个对象中的成员(引用类型),以指向另一个对象(不同类型)的私有成员。我使用friend来提供对私有成员的访问。(请稍等,我将进一步解释为什么我需要这样做。)

下面是我试图开始使用的代码的最小版本,它显然不起作用。现在很明显,我只是试图用这个代码Aries a(t.Leo);初始化引用,但是因为这是在main()内部完成的,所以它不会编译。

我在这里和互联网上(关于friendreference的主题)浏览了许多帖子,但无法找到解决它的方法。我该如何使其工作,或者我可以尝试其他什么方法来正确绑定引用?

class Aries;
class Taurus {
friend class Aries;
public:
  void setLeo(int inLeo) {
    Leo = inLeo;
  }
private:
  int Leo;
};
class Aries {
public:
  Aries(const int& inCancer) : Cancer(inCancer) {}
private:
  const int& Cancer;
};
int main() {
  Taurus t;
  Aries a(t.Leo);  // Intention: initialize (bind) the Cancer member with t's Leo.
}

注释我对c++有足够的了解,可以理解为什么上面的做法被认为是有问题的或不好的。

我正在一个硬件模拟环境的研究项目中工作,其中测试台架是用c++编写的。该项目的目的是将类(私有)成员显示为波形。这样做的唯一可靠的方法是使"波形制造者"类作为testbench对象的friend,然后让它"跟踪"私有成员(通过如上所述创建reference)。在测试台中提供getter方法的另一种替代方法是不切实际的,因为这个项目将与20年的遗留代码一起使用。

Aries构造函数更改为使用Taurus引用,而不是直接使用私有的int。像这样:

class Aries;
class Taurus {
friend class Aries;
public:
  void setLeo(int inLeo) {
    leo = inLeo;
  }
private:
  int leo;
};
class Aries {
public:
  Aries(const Taurus& inTau) : Cancer(inTau.leo) {}
private:
  const int& Cancer;
};
int main() {
  Taurus t;
  Aries a(t);
}

我知道你知道friend是有问题的,但有时是必要的,但在这种情况下,这些类不必是朋友。

struct AriesBinder {
  AriesBinder(const int& c) : Cancer(c) {}
  const int& Cancer;
};
class Taurus {
public:
  void setLeo(int inLeo) {
    Leo = inLeo;
  }
  AriesBinder bind() const { return AriesBinder(Leo); }
private:
  int Leo;
};
class Aries {
public:
  Aries(const int& inCancer) : Cancer(inCancer) {}
  Aries(AriesBinder b) : Cancer(b.Cancer) {}
private:
  const int& Cancer;
};
int main() {
  Taurus t;
  Aries b(t.bind());  // Intention was made clear
}

如果像Taurus这样的许多对象可以绑定到Aries,这尤其有用。此外,它解耦了这两个类,因为现在它们不必相互知道,所以你可以改变Taurus的内部表示。

友谊的目的是允许访问与您的紧密耦合的某些类,通常是类工厂(在构造类时分配成员)或某些特殊的实现类。

因此,在你的情况下,如果白羊座是金牛座的朋友,你会期望两者之间有很强的耦合。

你的代码不工作,因为你正在访问金牛座。狮子座来自主星座,不是来自白羊座。

友好关系的目的特别在于不必为这些变量创建一个公共的"getter"。这是因为这些变量是"内部细节",您不希望公众访问它们,甚至不希望它们读取。

所以,虽然我希望上面的大多数答案都是可能的解决方案,并且可以编译和工作,但你必须理解友谊的概念,并为你的特定情况设计,看看它是否是一个合适的用途。