1

这是 C++ 如何工作的问题。

我一直在研究friend修饰符,并在此处找到了一个static friend方法示例

但是现在我很难理解为什么要采取某些措施来使其发挥作用。

我也很好奇这可以用于什么实际应用?什么时候使用static friend?应该避免这种情况吗?

这是添加了注释的代码,以指出我感到困惑的部分。

#include <iostream>

class A; //1. why declare class A here and define it below?

class B
{
public:
    B();
    ~B();

    static void SetAiPrivate(int value); //Makes SetAiPrivate static
    static A *pa; //static instance of class A for class B's static 
                  //methods to use
};

class A
{
friend void B::SetAiPrivate(int); //Gives Class B's SetAiPrivate method access
                                  //to A's private variables

public:
    A(){iPrivate = 0;}
    ~A(){}
    void PrintData(){ std::cout << "iPrivate = "<< iPrivate<<"\n";}

private:
    int iPrivate;
};


A *B::pa;//2. Why is this needed? 
         //   If commented out it causes an external linking error.

B::B()
{
    pa = new A;
}     
B::~B()
{
    delete pa;
}

void B::SetAiPrivate(int value)
{
    pa->iPrivate = value;
}

int main()
{
    B b; //3. Is this necessary? Doesn't C++ automatically initiate static
         //   member variables when a class is referenced

    B::SetAiPrivate(7);
    B::pa->PrintData();
    return 0;
}
4

2 回答 2

1

我们先来看代码:

A类;//1. 为什么在这里声明A类并在下面定义它?

这是一个前瞻性声明。B有一个 type 的成员A*,所以A必须事先声明。

A *B::pa;//2. 为什么需要这个?

静态数据成员仅在类定义中声明。这就是定义,标准要求它存在于单个翻译单元中。

乙乙; //3. 这是必要的吗?引用类时,C++ 不会自动初始化静态成员变量吗?

没有必要。除非当然static方法B依赖于构造函数的运行。如果他们这样做,这是一个糟糕的设计。

friend问题上。通常,有朋友会打破封装,无论是成员还是整个班级。这没有什么不同。它只是告诉编译器A::iPrivate可以从B::SetAiPrivate.

这在我看来是错误的,因为您可能希望能够A直接设置成员 from A,而不是 from B

于 2012-08-30T21:54:56.220 回答
1

1 为什么在这里声明A类并在下面定义呢?

如果 A 是在 B 类之后定义的,则需要转发声明 A,因为 B 类包含指向 A 实例的指针。如果您在 B 类之前定义了 A 类,则不需要

2 为什么需要这个?

静态成员必须在类定义之外的某个地方初始化

3 这有必要吗?引用类时,C++ 不会自动启动静态成员变量

AFAIK 知道由于您提到的原因,这不是必需的

于 2012-08-30T21:55:55.493 回答