简体   繁体   English

声明友元函数时的变量范围错误

[英]Variable scope error when declaring friend function

Friend functions can't access variables of the classes 朋友函数无法访问类的变量

I'm having a problem with several friend functions not being able to access the variables in classes where they have been declared as friends. 我遇到了几个朋友函数无法访问已被声明为朋友的类中的变量的问题。

The actual error text is: error: 'fid' was not declared in this scope. 实际的错误文本是:错误:在此范围内未声明'fid'。 this repeats for the other private variables. 这会重复其他私有变量。 The same error is given for three functions, read, negative, and write. 对于三个函数(读取,否定和写入)给出了相同的错误。

A couple of notes: 1) This lab requires that I write the code so that the functions can be used by both classes. 几个注意事项:1)本实验要求我编写代码,以便两个类都可以使用这些函数。

I'm compiling this in windows with code::blocks using g++ and I've also tried compiling my code in ubuntu using g++ from the terminal using the -g flag and I get the same error both times. 我正在使用g ++编写带有code :: blocks的windows中的这个,我也尝试使用-g标志从终端使用g ++在ubuntu中编译我的代码,我两次都得到相同的错误。

Any suggestions you have would be greatly appreciated. 您的任何建议将不胜感激。

Header File 头文件

#ifndef PXMUTILS_H
#define PXMUTILS_H

#include <cstdio>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>

using namespace std;
typedef unsigned char uchar;

class pgm
{
public:
    pgm();
    ~pgm();
    void read(string &);
    void negative();
    void write(string);
    friend void read (const string &);
    friend void write(string);
    friend void negative();
private:
    int nr;
    int nc;
    int mval;
    int ftyp;
    string fid;
    uchar **img;
};

class ppm
{
public:
    ppm();
    ~ppm();
    void read(string &);
    void negative();
    void write(string);
    friend void read (const string &);
    friend void write (string);
    friend void negative ();
private:
    int nr;
    int nc;
    int mval;
    int ftyp;
    string fid;
    uchar **img;
};

#endif

C++ program C ++程序

#include <cstdio>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include "pxmutils.h"

using namespace std;
typedef unsigned char uchar;

uchar ** newimg(int nr, int nc, int ftyp)
{
uchar **img=new uchar *[nr];
img[0]=new uchar [nr*nc*ftyp];
for(int i=1; i<nr; i++)
    {
        img[i]=img[i-1]+nc*ftyp;
    }
    return img;
}

void deleteimg(uchar **img)
{
    if(img)
    {
        if(img[0])
        {
            delete [] img[0];
        }
        delete [] img;
    }
}
void read (const string &fname)
{
    ifstream fin(fname.c_str(), ios::in);
    if(!fin.is_open())
    {
        cerr<<"Could not open "<<fname<<endl;
        exit(0);
    }
    fin >>fid
        >>nc
        >>nr
        >>mval;
        while (fin.get() != '\n') { /*skip to EOL */ }

    img=newimg(nr, nc);
    fin.read((char *)img[0], nr*nc);
    fin.close();
    }

void set_cmap(string mname)
{
}

void negative()
{
    for(int i=0; i<nr; i++)
    {
        for(int j=0; j<nc; j++)
        {
           int t=img[i][j];
           img[i][j]=(255-t);
        }
    }
}

void write(string fname)
{
        ofstream fout (fname.c_str(), ios::out);
        size_t dp;
    if ((dp = fname.rfind(".pgm")) != string::npos)
        {
            fout<<"P5"<<endl;
        }
        if((dp= fname.rfind(".ppm")) != string::npos)
        {
            fout<<"P6"<<endl;
        }
        fout<<nc<<" "<<nr<<endl;
        fout<<mval<<endl;

    for(int i=0; i <nr; i++)
    { 
        for (int j=0; j<nc; j++)
        {
            fout<<img[i][j]<<" ";
        }
        fout<<endl;
    }

    fout.close();
}

pgm::pgm()
{
    nr=0;
    nc=0;
    mval=0;
    ftyp=1;
    fid="";
    img=NULL;
}

pgm::~pgm()
{
    deleteimg(img);
}

ppm::ppm()
{
    nr=0;
    nc=0;
    mval=0;
    ftyp=1;
    fid="";
    img=NULL;
}

ppm::~ppm()
{
    deleteimg(img);
}

Program to test functions 程序测试功能

#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

#include "pxmutils.h"

int main(int argc, char *argv[])
{
    if (argc == 1) {
        cerr << "No input file specified!\n";
        exit(0);
    }

    string fname = argv[1];
    size_t dp;

    if ((dp = fname.rfind(".pgm")) == string::npos) {
        cout << "PGM error: file suffix " << fname
             << " not recognized\n";
        exit(0);
    }

    fname.erase(dp);

pgm img_g;
    ppm img_c;

    img_g.read(fname+".pgm");

    if (argc == 3)    
    img_c.set_cmap(argv[2]);

    img_c = img_g;

    img_g.negative();

    img_g.write(fname+"_n.pgm");
    img_c.write(fname+"_c.ppm");
}
fin >>fid
    >>nc
    >>nr
    >>mval;
    while (fin.get() != '\n') { /*skip to EOL */ }

In this code, fid, nc, nr etc are undefined. 在此代码中,fid,nc,nr等未定义。 You need to use the class instance to be able to access them, they don't exist by themselves. 您需要使用类实例才能访问它们,它们本身并不存在。

Your functions don't accept the class objects as parameters, so how are you going to read into them? 您的函数不接受类对象作为参数,那么您将如何读入它们?

You should have another think of your design. 你应该考虑一下你的设计。 It is best to avoid friend functions if possible, 如果可能,最好避免使用friend功能,

You need to go a bit back to basics. 你需要回到基础。 When you define non-static members of a class you are defining attributes or operations of the objects of the class, but those attributes don't exist by themselves, only as part of the instances of the class. 定义类的非静态成员时,您要定义类的对象的属性操作 ,但这些属性本身不存在,仅作为类的实例的一部分。

This concept is orthogonal to access and access specifiers , that is, this is so regardless of the members being public , protected or private . 这个概念与访问访问说明符是正交的,也就是说,无论成员是publicprotected还是private ,都是如此。 Once you have an instance, when your try to access those members the access specifiers come into play, and there is where friendship comes into play: it will grant your code access to members that would otherwise be inaccessible ( private or protected outside of the inheritance hierarchy). 一旦你有了一个实例,当你尝试访问这些成员时, 访问说明符就会发挥作用, 友谊就会发挥作用:它会授予你的代码访问权限,否则这些成员将无法访问( privateprotected的继承)层次)。

The problem in your code is that you don't have an object, and thus cannot access the members of the object. 代码中的问题是您没有对象,因此无法访问对象的成员。 You will need to either create or pass an object of the appropriate type to the functions. 您需要为函数创建或传递适当类型的对象。

There are other problems in the code, like for example, the memory allocations inside newimg look a little suspicious (what were you intending to allocate?) but that is outside of the scope of this question. 代码中还有其他问题,例如, newimg的内存分配看起来有点可疑(你打算分配什么?)但这超出了这个问题的范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM