2013-01-03 201 views
0

我想初始化一个对象中的成员(引用类型),指向另一个对象(不同类型)的私有成员。我使用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++编写的。该项目的目标是将班级(私人)成员显示为波形。这样做的唯一可靠方法是将“波形制造者”类作为测试台对象的friend,然后让它“追踪”私有成员(通过创建如上所述的reference)。在测试平台中提供getter方法的另一种方法是不切实际的,因为这个项目将使用20年的遗留代码。

+0

耐人寻味的名称混淆... – Chowlett

+0

@Chowlett哈哈,富酒吧巴兹是不够的时候。 –

回答

1

我知道你知道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的内部表示。

+0

你的推理是有效的和有用的。我遇到的问题是我必须对“金牛座”类(这是客户的代码)进行最小限度的更改。我最初努力弄清楚这是否可以在没有任何代码改变的情况下完成,但由于没有符合标准的访问私人成员的方法(并且这是一个骗局,即使有可能通过一些黑客),我只做一个更改(添加朋友声明)。我个人更喜欢非朋友版本(如您的代码),但业务考虑因素会覆盖工作中的技术版本。 :S –

2

只需更改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); 
} 
0

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

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

你的代码不起作用,因为你是从main,而不是从白羊座访问Taurus.Leo。

友谊的目的特别是不必为这些变量创建一个公共的“getter”。这是因为这些变量是“内部细节”,您不希望整个公众访问,甚至不需要阅读。

因此,虽然我希望大多数的答案以上是可能的解决方案,并编制和工作,你必须明白友谊和设计理念,为您的具体情况,看它是否是一个合适的使用。

+0

虽然我不是C++专家,但我知道这一点,并且同意你所说的所有内容。但问题是我没有设计模拟环境的其余部分。最初的建筑是20多年前设计的。如果当时已经考虑过这个项目,他们可能会设计成可以避免友谊,但现在我的任务主要是在20年的遗留代码中“修补”一项新功能。正如你可以想象的那样,它会变得丑陋,但我试图尽可能减少丑陋。 –