C++ C++;作为朋友的成员功能

C++ C++;作为朋友的成员功能,c++,friend,C++,Friend,我有两个类,即A和B,有以下独立声明 class A { private: std::vector<B> vec = {B("X","Y")}; public: A(); void clear(std::vector<B>::size_type index); }; class B { private: std::string m_first; std::string m_second; p

我有两个类,即A和B,有以下独立声明

class A {
private:
    std::vector<B> vec = {B("X","Y")};
public:
    A();
    void clear(std::vector<B>::size_type index);
};

class B {
private:
    std::string m_first;
    std::string m_second;
public:

    B() = default;
    B(std::string first, std::string second) : m_first(first), m_second(second) {}
    
    // I want the friend below - how to do it?
    friend void A::clear(std::vector<B>::size_type index);
};
A类{
私人:
向量向量={B(“X”,“Y”)};
公众:
A();
空白清除(标准::向量::大小\类型索引);
};
B类{
私人:
std::首先是字符串m_;
std::字符串m_秒;
公众:
B()=默认值;
B(std::string first,std::string second):m_first(first),m_second(second){
//我想要下面的朋友-怎么做?
友元void A::clear(std::vector::size\u类型索引);
};

< P> >我想声明<代码>无效A::清除(STD::vector:sisi-Type index)< /C> > B类的朋友。C++有可能吗?我不能为A做B的前向声明,因为A需要使用2个参数查看B的构造函数。

我99%确信,您要求将
A::clear
作为
B
的朋友,这是一种耦合过紧的情况。这就是友谊。想想另一种方法

请编辑问题并提供你认为你需要友谊的理由。这些类之间的关系到底是什么,用例是什么?说服我们需要友谊,因为我看不出来

我所能说的最好的情况是
B
的构造函数的签名在复制参数时是浪费的(通过按值获取参数)。除非需要在方法/构造函数中修改副本,否则这些参数应该由const引用获取。我已经在下面修好了

A
需要查看带有2个参数的
B
构造函数

没有<代码>A没有。只有
的构造函数才能执行以下操作:

#pragma once
#include <string>
#include <vector>

class B;

class A {
private:
    std::vector<B> vec;
public:
    A();
    void clear(std::vector<B>::size_type index);
};

class B {
private:
    std::string m_first;
    std::string m_second;
public:

    B() = default;
    B(const std::string &first, const std::string &second) : 
        m_first(first),m_second(second)  {}
    friend void A::clear(std::vector<B>::size_type index);
};

inline A::A() : vec{ B("X", "Y") } {}

您已经设置好了类
A
需要在
B
之前定义(因此
B
可以将
A
的成员声明为
朋友
),但同时
B
需要在
A
之前定义(因此可以使用
B
的构造函数初始化
A
vec
成员)

这是一种循环依赖关系(定义
a
必须在定义
B
之前,B
必须在定义
a
-无限之前)

除非事先定义了类,否则无法将类的成员声明为朋友

你需要打破这种循环依赖关系——要么不让
A::clear()
成为
B
朋友,要么不在类定义中初始化
A
vec
成员(这意味着你只需要在
A
的构造函数中初始化
vec

或者,可以将
A
声明为
B
friend
,而无需事先定义
A
(即,先前声明
A
就足够了,无需对其进行定义)。因此,另一种选择可能是将
A
声明为
B
朋友,而不仅仅是
A::clear()


这意味着必须先定义
B
,然后才能定义
A
B
,而不必查看
A

A是B的管理者,即在程序中,所有B实体都由A管理。我可以想出两种方法。在B中添加成员函数以自行清除它或使用友谊(如上)当你说它的友谊被误用时,你是什么意思?另外,当我们定义友谊时,我们不是真的打算把类结合起来吗?如果
a
想要管理
B
,那么
a
应该是
B
的朋友。整个事情,不仅仅是一个方法。但是既然
B
的构造函数是公共的,它就不是在我看来,不要像“管理”
A
“管理”
B
。以您认为的方式管理的对象具有约束。例如,您不能将它们放入向量(它不会编译)-由于
std::vector
不知道如何使用
A
管理
B
!要声明
A
管理
B
,您需要将
B
的构造函数设置为私有(或受保护)换句话说,C++中的管理者和MaGees之间的紧密耦合是不可能一路完成的。一旦代码> B/java >构造函数是私有的,只有<代码> A/CUT>可以访问它们,那么没有标准容器可以在<代码> B<代码>上工作。不,使<代码> STD::向量< /代码>朋友Of
B
不能保证做到这一点(在许多实现中,它也不能做到)因此,相反,可以将
A
视为
B
的合作伙伴。例如,如果
B
想通知
A
它的存在,那么可以采取不同的方式。啊,我明白了。我没有完全理解你的问题,UnslanderMonica的编辑清楚地表明了这一点。我已经删除了我的评论。转发声明很简单。只是广告d
class B;
class A{
#pragma once
#include <string>
#include <vector>

class B {
private:
    std::string m_first;
    std::string m_second;
public:
    class A {
    private:
        std::vector<B> vec = {B("X","Y")};
    public:
        void clear(const std::vector<B>::size_type &index);
    };

    B() = default;
    B(const std::string &first, const std::string &second) : 
        m_first(first),m_second(second)  {}
    friend void A::clear(const std::vector<B>::size_type &index);
};

using A = B::A;