friend函数无权访问私有类成员

时间:2018-04-15 16:35:25

标签: c++ operator-overloading

我还是C ++的新手,作为作业的一部分,我编写了一个需要重载流提取操作符的类'>>'对于文件流提取,为了使事情更容易,所以说明。我已经为两个运算符声明并定义了2个重载,一个用于iostream对象的oveload和一个用于fstream对象的重载。现在,一切都很好,直到我得到'>>'的定义。对于文件流对象,显然该函数无法访问其所属类的私有(或受保护)成员。

这是我的代码,我提前感谢你们所有人:

stock.h

#ifndef STOCK_H
#define STOCK_H
#include<iostream>
#include<fstream>


class Stock_Type 
{
    friend std::ostream& operator<<(std::ostream&, const Stock_Type&);
    friend std::istream& operator>>(std::istream&, Stock_Type&);
    friend std::ofstream& operator<<(std::ofstream&, const Stock_Type&);
    friend std::ifstream& operator>>(std::ofstream&, Stock_Type&);

    public:

        //constructor overloads-----------------------------------------------------------------------------------------------------
        Stock_Type(){};
        Stock_Type(std::string sym, double a, double b, double c, double d, double e, int f, double g) :
            stock_symbol(sym), opening_price(a), closing_price(b), high_price(c), low_price(d), prev_close(e), volume(f), percent_gain(g) {}

        //default destructor--------------------------------------------------------------------------------------------------------
        ~Stock_Type(){};

        //accessor functions--------------------------------------------------------------------------------------------------------
        void set_Symbol(std::string x){stock_symbol = x;}
        void set_Closing_Price(double x){closing_price = x;}
        void set_High_Price(double x){high_price = x;}
        void set_Low_Price(double x){low_price = x;}
        void set_Prev_Close(double x){prev_close = x;}
        void set_Volume(int x){volume = x;}

        std::string get_Stock_Smybol(){return stock_symbol;}
        double get_Opening_Price(){return opening_price;}
        double get_Closing_Price(){return closing_price;}
        double get_High_Price(){return high_price;}
        double get_Low_Price(){return low_price;}
        double get_Prev_Close(){return prev_close;}
        int get_Volume(){return volume;}
        double get_Percent_Gain_Loss(){return get_Closing_Price() - get_Opening_Price();}

        //operations on Stock_Type-------------------------------------------------------------------------------------------------------


        //operator functions--------------------------------------------------------------------------------------------------------------
        bool operator==(const Stock_Type&)const;
        bool operator!=(const Stock_Type&)const;
        bool operator<(const Stock_Type&) const;
        bool operator<=(const Stock_Type&)const;
        bool operator>(const Stock_Type&)const;
        bool operator>=(const Stock_Type&)const;
        friend std::ostream& operator<<(std::ostream&, const Stock_Type&);
        friend std::istream& operator>>(std::istream&, Stock_Type&);
        const Stock_Type& operator=(const Stock_Type &right_operand);

        Stock_Type& operator[](int elem);
        const Stock_Type& operator[](int elem) const;


    private:
        std::string stock_symbol;//record data1
        double opening_price, closing_price, high_price, low_price, prev_close;//record data2
        int volume;//record data3
        double percent_gain;//record data 4
        Stock_Type *stock_pointer;
        int array_size;


};





#endif

stock.cpp,我只会包含生成错误的函数

std::ifstream& operator>>(std::ifstream& if_obj, Stock_Type& stock_obj)
{
    if_obj >> stock_obj.stock_symbol 
          >> stock_obj.opening_price
          >> stock_obj.closing_price 
          >> stock_obj.high_price
          >> stock_obj.low_price
          >> stock_obj.prev_close
          >> stock_obj.volume
          >> stock_obj.percent_gain;

    return if_obj;
}

错误是列出的所有属性都是&#34;无法访问&#34;

我想完成这项任务,因为我想转到另一个应对异常处理的任务。

再次感谢大家。

2 个答案:

答案 0 :(得分:0)

我道歉,我相信定义和实现中的签名是不同的,正如之前的评论所指出的,我宣布了两次朋友功能,在那里我看到了我的错误,我没有在复制/粘贴后更改代码它。对于所有未来的读者:确保解密签名与实施签名相匹配!

答案 1 :(得分:0)

有一个

var itemSize = 15;
var cellSize = itemSize - 1;
var margin = {top: 50, right: 20, bottom: 20, left: 150};
var width = 445 - margin.right - margin.left;
var height = 430 - margin.top - margin.bottom; 

var svg = d3.select('#heatmap')
    .append('svg')
    .attr('width', width + margin.left + margin.right)
    .attr('height', height + margin.top + margin.bottom)
    .append('g')
    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

var colorScale = d3.scaleLinear()
    .domain([0, 85, 100])
    .range(['white', 'tomato', 'steelblue']);

svg.append('defs')
    .append('pattern')
        .attr('id', 'pattern-stripes')
        .attr('patternUnits', 'userSpaceOnUse')
        .attr('patternTransform', 'rotate(45)')
        .attr('width', 3)
        .attr('height', 3)
        .append('rect')
            .attr('width', 1)
            .attr('height', 3)
            .attr('transform', 'translate(0, 0)')
            .attr('fill', 'black');

d3.queue()
    .defer(d3.csv, './data.csv')
   .await(create);

function create(err, data) {
    if(err) {
      console.log('Error loading files:', err);
      throw error;
    }
   var data = data.map(function(item) {
        var newItem = {};
        newItem.nuts_id = item.NUTS_ID;
        newItem.nuts_name = item.NUTS_NAME;
        newItem.year = item.YEAR;
        newItem.valuePol = item.POL;
        return newItem;
    });

    var years = data.map(function(d) {
        return d.year;
    });
    var x_elements = d3.set(years).values();

    var nuts_names = data.map(function(d) {
        return d.nuts_name;
    });
    var y_elements = d3.set(nuts_names).values();

    var xScale = d3.scaleBand()
        .domain(x_elements)
        .range([0, x_elements.length * itemSize]);

    var xAxis = d3.axisTop(xScale)
        .tickFormat(function(d) {
            return d; // d is the year
        });

    var yScale = d3.scaleBand()
        .domain(y_elements)
        .range([0, y_elements.length * itemSize]);

    var yAxis = d3.axisLeft(yScale)
        .tickFormat(function(d) {
            return d; // d is the region
        }); 

    var cells = svg.selectAll('rect')
        .data(data)
        .enter()
        .append('g')
        .append('rect')
        .attr('class', 'cell')
        .attr('width', cellSize)
        .attr('height', cellSize)
        .attr('x', function(d) { 
            return xScale(d.year); 
        })
        .attr('y', function(d) { 
            return yScale(d.nuts_name); 
        })
        .attr('fill', function(d) {
            var col;
            if(d.valuePol == '') {
                col = 'url(#pattern-stripes)';
            }
            else {
                col = colorScale(d.valuePol); 
            }
            return col;
        });

    svg.append('g')
        .attr('class', 'y axis')
        .call(yAxis)
        .selectAll('text')
        .attr('font-weight', 'normal');

    svg.append('g')
        .attr('class', 'x axis')
        .call(xAxis)
        .selectAll('text')
        .attr('font-weight', 'normal')
        .style('text-anchor', 'start')
        .attr('dx', '.8em')
        .attr('dy', '.5em')
        .attr('transform', function(d) {
            return 'rotate(-65)';
        });
}

但您在

中遇到了访问问题
friend std::ifstream& operator>>(std::ofstream&, Stock_Type&);

添加其他朋友应该有所帮助。

std::ifstream& operator>>(std::ifstream& if_obj, Stock_Type& stock_obj)

实际上,您可能更喜欢编辑现有的朋友,它看起来像是一个错字或其他类似的小错误。