C++ 初始化朋友';s引用成员到类私有成员

C++ 初始化朋友';s引用成员到类私有成员,c++,reference,friend,c++03,C++,Reference,Friend,C++03,我想初始化一个对象中的成员(引用类型)以指向另一个对象(不同类型)的私有成员。我使用friend访问私人成员。(请容忍我一点,我进一步解释我为什么需要这样做。) 下面是我尝试开始使用的代码的最低版本,显然不起作用。现在很明显,我只想用这个代码初始化引用Aries a(t.Leo),但由于这是在main()中完成的,因此它不会编译 我在这里和互联网上浏览了许多帖子(关于朋友和参考),但没有找到解决办法。我怎样才能做到这一点,或者有什么其他方法可以尝试正确绑定引用 class Aries; cla

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

下面是我尝试开始使用的代码的最低版本,显然不起作用。现在很明显,我只想用这个代码初始化引用
Aries a(t.Leo),但由于这是在
main()
中完成的,因此它不会编译

我在这里和互联网上浏览了许多帖子(关于
朋友
参考
),但没有找到解决办法。我怎样才能做到这一点,或者有什么其他方法可以尝试正确绑定引用

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对象的朋友,然后让它“跟踪”私有成员(如上所述创建一个
引用)。在测试台中提供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);
}

只需将
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
),这一点尤其有用。另外,它将这两个类分离开来,因为现在不必相互了解,所以您可以更改
金牛座的内部表示形式
我知道
朋友
是有问题的,但有时是必要的,但在这种情况下,这些类不必是朋友

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”。这是因为这些变量是“内部细节”,您不希望广大公众访问,甚至不希望阅读


因此,虽然我希望上面的大多数答案都是可能的解决方案,并且能够编译和运行,但您必须了解友谊的概念,并针对您的特定案例进行设计,以确定它是否是一种适当的用途。

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

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

你的代码不起作用,因为你正在访问金牛座。狮子座从主要,而不是从白羊座

友谊的目的尤其是不必为这些变量创建公共“getter”。这是因为这些变量是“内部细节”,您不希望广大公众访问,甚至不希望阅读


因此,虽然我希望上面的大多数答案都是可能的解决方案,并将编译和运行,但您必须了解友谊的概念,并针对您的特定案例进行设计,以确定它是否适合使用。

有趣的名称混淆…@Chowlett ha,有时候,foo-bar-baz是不够的。有趣的名字混淆…@Chowlett-ha,foo-bar-baz有时候是不够的。你的推理是有效的,也是有用的。但我的问题是,我必须对
Taurus
类(这是客户的代码)进行最小的更改。我最初试图弄清楚这是否可以在没有任何代码更改的情况下完成,但由于没有符合标准的方式访问私人成员(这是一个骗局,即使通过一些黑客可以实现),我决定只做一个更改(添加一个朋友声明)。我个人更喜欢非好友版本(如您的代码),但工作中的业务考虑凌驾于技术考虑之上:你的推理是有效和有用的。但我的问题是,我必须对
Taurus
类(这是客户的代码)进行最小的更改。我最初试图弄清楚这是否可以在没有任何代码更改的情况下完成,但由于没有符合标准的方式访问私人成员(这是一个骗局,即使通过一些黑客可以实现),我决定只做一个更改(添加一个朋友声明)。我个人更喜欢非好友版本(如您的代码),但工作中的业务考虑凌驾于技术考虑之上:虽然我不是C++专家,但我对它很了解,并且同意你所说的一切。但问题是我做到了