为啥这个朋友功能不能访问类的私有成员?

Posted

技术标签:

【中文标题】为啥这个朋友功能不能访问类的私有成员?【英文标题】:Why this friend function can't access a private member of the class?为什么这个朋友功能不能访问类的私有成员? 【发布时间】:2010-03-23 14:29:51 【问题描述】:

当我尝试从 extractHistogram() 实现中访问 GHistogram 类的 bins 私有成员时,出现以下错误:

error: 'QVector<double> MyNamespace::GHistogram::bins' is private
error: within this context

“在此上下文中”错误指向 extractHistogram() 实现。有谁知道我的朋友函数声明有什么问题?

代码如下:

namespace MyNamespace

class GHistogram


public:
    GHistogram(qint32 numberOfBins);
    qint32 getNumberOfBins();

    /**
     * Returns the frequency of the value i.
     */
    double getValueAt(qint32 i);
    friend GHistogram * MyNamespace::extractHistogram(GImage *image, 
                                                      qint32 numberOfBins);

private:
    QVector<double> bins;
;

GHistogram * extractHistogram(GImage * image, 
                              qint32 numberOfBins);

 // End of MyNamespace

【问题讨论】:

Gbdi 是类还是命名空间?你有Gbdi::extractHistogram 作为朋友。 抱歉,将 Gbdi 替换为 MyNamespace。 GBDI 是我工作的研究小组的名称... 【参考方案1】:

根据我的 GCC,上面的代码无法编译,因为 extractHistogram() 的声明出现在它是 friended 的类定义之后。编译器在friend 语句上窒息,说extractHistogram 既不是函数也不是数据成员。一切正常,当我将声明移到类定义之前(并添加前向声明 class GHistogram; 以便编译器知道返回类型)时,可以访问 bins。当然extractHistogram() 的代码应该写在命名空间内,要么由

namesapce MyNameSpace 
// write the function here

GHistogram *MyNameSpace::extractHistogram( //....

【讨论】:

谢谢!我曾尝试在类声明之前声明 extractHistogram() ,但它不起作用,因为它在函数实现中缺少命名空间范围——我认为我只需要使用“使用命名空间”子句...... 【参考方案2】:

试试吧:

friend GHistogram *extractHistogram(GImage *image, qint32 numberOfBins);

【讨论】:

对不起我的错误。正确的是代码中的 MyNamespace 而不是 Gbdi。当我删除 MyNamespace 时,我得到了同样的错误。【参考方案3】:

您声明Gbdi::extractHistogram 成为GHistogram 的朋友,但您声明了一个名为extractHistogram函数,并希望它与GHistogram 成为朋友。 extractHistogram 应该是 Gbdi 的成员。

【讨论】:

对不起我的错误。正确的是代码中的 MyNamespace 而不是 Gbdi。【参考方案4】:

我猜你的意思是:

 friend GHistogram * extractHistogram(GImage *image, qint32 numberOfBins);

这可能不是原因,而是一个建议:

还有一点,如果一个函数是该类的朋友并且您已经在该类中声明了该函数,则您无需在该类之外声明该函数。

换句话说:

//Your.h
class Foo

friend void m();

void m(); //This is totally unnecessary

//Your.cpp
void m()


【讨论】:

但是如果我这样做了,当我尝试从'main.cpp' 中的 int main() 调用 m() 时,我会收到一个错误,告诉我 'm() 不是即使我在我的 'main.cpp' 中包含了 'Your.h',也要在这个范围内声明。 你完全正确。它让我忘记了,因为我通常不这样做。我会删除那个。对不起。

以上是关于为啥这个朋友功能不能访问类的私有成员?的主要内容,如果未能解决你的问题,请参考以下文章

为啥嵌套的子类可以访问其父类的私有成员,而孙子却不能?

为啥我不能访问 TypeScript 私有成员?

C#中继承类为啥可以通过属性访问基类的私有字段。

为啥我的函数不能访问它所在类的私有变量 INSIDE?

在Java中,如果这样写,为啥私有数据成员可以在类外部访问? [复制]

继承和多态