【问题标题】:C++ Accessing an element of a private array from a friend function (operator <<)C++ 从友元函数访问私有数组的元素(运算符 <<)
【发布时间】:2019-06-05 22:40:20
【问题描述】:

我有一个具有以下声明和随附定义的类:

friend ostream& operator<<(ostream& out, const Poly& poly);
ostream& operator<<(ostream& out, const Poly& poly) {}

private:
    int *polyArray;

在该运算符函数的代码中,我有(除其他外):

    if (poly.polyArray[i] != 0) {
        out << poly.polyArray[i];
    }

我从编译器 (Visual Studio) 中的下划线收到以下错误消息,特别是在“polyArray”下方:

int *Poly::polyArray 
Member "Poly::polyArray" is inaccessible

我能够很好地调用公共成员函数,并且我认为我能够从朋友函数访问私有数据成员。

关于我为什么会收到此错误的任何想法?

注意: 根据要求,以下是完整课程的更多内容:

首先是头文件。

class Poly
{
public:
    Poly(int coeff, int expon);
    friend ostream& operator<<(ostream& out, const Poly& poly);
private:
    int *polyArray;
    int size;
};

然后是实现。

#include <iostream>
#include "Poly.h"

using namespace std;

Poly::Poly(int coeff, int expon) {
    size = expon + 1;
    polyArray = new int[size];
    for (int i = 0; i < size; ++i) {
        polyArray[i] = (i == expon ? coeff : 0);
    }
}

ostream& operator<<(ostream& out, const Poly& poly) {
    int currentSize = poly.getSize();
    // If Poly is "empty", print 0
    if (currentSize == 1 && poly.polyArray[0] == 0) {
        out << 0;
        return out;
    }
    for (int i = 0; i < currentSize; ++i) {
        // Print the "+" sign if the coefficient is positive
        //if (poly.polyArray[i] > 0) {
        if (poly.polyArray[i] > 0) {
            out << "+";
        }
        // Print the coefficient if it is not 0, skipping it and all following code otherwise
        if (poly.polyArray[i] != 0) {
            out << poly.polyArray[i];
        }
        else {
            continue;
        }
        // Print "x" if the exponent is greater than 0
        if (i > 0) {
            out << "x";
        }
        // Print exponent if it is greater than 1
        if (i > 1) {
            out << "^" << i;
        }
        // Print a space if this is not the last term in the polynomial
        if (i != currentSize - 1) {
            out << " ";
        }
    }
    return out;
}

最后,主要的。

#include "Poly.h"
#include <iostream>

using namespace std;

int main() {
    Poly y(5, 7);
    cout << y;
    return 0;
}

【问题讨论】:

  • 非常确定 - 我编辑了我的原始帖子以在声明旁边添加定义标题。我只是复制/粘贴它并没有改变任何东西。对我来说它看起来一样 - 我错过了什么吗?
  • Poly 是否在命名空间范围内声明?
  • Caleth,你是什么意思?
  • 我发现了问题并更新了我的答案!

标签: c++ private friend


【解决方案1】:

使用命名空间的指令(例如using namespace std)仅适用于在指令之后编写的代码和头文件。

在您的头文件Poly.h 中,没有ostream 的定义,因为ostream 在命名空间std 中。有三种可能的修复方法:

  • 头文件中的using namespace std(不好的做法)
  • 头文件中的using std::ostream
  • 使用全名std::ostream

    friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, const Poly&amp; poly);

如果我们应用第二个修复,这就是我们的文件现在的样子。

Poly.h

#include <iostream>

using std::ostream; 

class Poly
{
public:
    Poly(int coeff, int expon);
    friend ostream& operator<<(ostream& out, const Poly& poly);
private:
    int *polyArray;
    int size;
};

Poly.cc

#include <iostream>
#include "Poly.h"
using namespace std;

Poly::Poly(int coeff, int expon) {
    size = expon + 1;
    polyArray = new int[size];
    for (int i = 0; i < size; ++i) {
        polyArray[i] = (i == expon ? coeff : 0);
    }
}

ostream& operator<<(ostream& out, const Poly& poly) {
    int currentSize = poly.getSize();
    // If Poly is "empty", print 0
    if (currentSize == 1 && poly.polyArray[0] == 0) {
        out << 0;
        return out;
    }
    for (int i = 0; i < currentSize; ++i) {
        // Print the "+" sign if the coefficient is positive
        //if (poly.polyArray[i] > 0) {
        if (poly.polyArray[i] > 0) {
            out << "+";
        }
        // Print the coefficient if it is not 0, skipping it and all following code otherwise
        if (poly.polyArray[i] != 0) {
            out << poly.polyArray[i];
        }
        else {
            continue;
        }
        // Print "x" if the exponent is greater than 0
        if (i > 0) {
            out << "x";
        }
        // Print exponent if it is greater than 1
        if (i > 1) {
            out << "^" << i;
        }
        // Print a space if this is not the last term in the polynomial
        if (i != currentSize - 1) {
            out << " ";
        }
    }
    return out;
}

main.cc

#include <iostream>
#include "Poly.h"

using namespace std; 

int main() {
    Poly y(5, 7);
    cout << y;
    return 0;
}

【讨论】:

  • 您和另一位发帖人对不匹配有相同的想法,所以我用定义标题的复制/粘贴编辑了我的原始帖子。看看 - 我错过了什么?
  • 你能发布一个不能编译的最小代码示例吗?能不能发一个完整的类,main方法,friend方法?
  • 当然,我刚刚用相关信息编辑了我的原始帖子。
  • 标头实际上不需要&lt;iostream&gt; - &lt;iosfwd&gt; 就足够了(并且最少)。
  • 第一个问题:“使用命名空间标准”被认为是不好的做法,因为它增加了两个不同类具有相同名称的可能性。例如,如果有std::string,但也有boost::string,并且您使用这两个命名空间,就会发生冲突(因为它们都是名称字符串)。第二个问题:它没有。您仍然可以使用好友功能访问私人数据成员。第三个问题:在头文件中包含 iostream 的目的是在使用该头文件中定义的类之前,您始终必须包含头文件。
猜你喜欢
  • 2023-03-24
  • 1970-01-01
  • 2016-09-09
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 2021-05-29
  • 1970-01-01
相关资源
最近更新 更多