0

フレンド関数はクラスの変数にアクセスできません

いくつかのフレンド関数が、フレンドとして宣言されているクラスの変数にアクセスできないという問題があります。

実際のエラー テキストは次のとおりです。エラー: 'fid' はこのスコープで宣言されていません。これは、他のプライベート変数に対して繰り返されます。read、negative、write の 3 つの関数で同じエラーが発生します。

いくつかの注意事項: 1) このラボでは、両方のクラスで関数を使用できるようにコードを記述する必要があります。

g++ を使用して code::blocks を使用して Windows でこれをコンパイルしています。また、ターミナルから -g フラグを使用して g++ を使用して ubuntu でコードをコンパイルしようとしましたが、どちらも同じエラーが発生します。

あなたが持っている提案は大歓迎です。

ヘッダー ファイル

#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++ プログラム

#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);
}

機能をテストするプログラム

#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");
}
4

3 に答える 3

2
fin >>fid
    >>nc
    >>nr
    >>mval;
    while (fin.get() != '\n') { /*skip to EOL */ }

このコードでは、fid、nc、nrなどは未定義です。それらにアクセスできるようにするには、クラスインスタンスを使用する必要があります。それらは、それ自体では存在しません。

関数はクラスオブジェクトをパラメータとして受け入れないので、どのようにそれらを読み込みますか?

于 2011-09-12T07:08:12.793 に答える
0

基本に少し戻る必要があります。クラスの非静的メンバーを定義する場合、クラスのオブジェクトの属性または操作を定義しますが、それらの属性はそれ自体では存在せず、クラスのインスタンスの一部としてのみ存在します。

この概念は、アクセスおよびアクセス指定子と直交しています。つまり、メンバーが、、またはであるかどうかに関係なく、これpublicprotected直交していますprivate。インスタンスを作成したら、それらのメンバーにアクセスしようとすると、アクセス指定子が機能し、友情が機能します。これにより、他の方法ではアクセスできない(privateまたはprotected継承階層の外にある)メンバーにコードアクセスが許可されます。 。

コードの問題は、オブジェクトがないため、オブジェクトのメンバーにアクセスできないことです。適切なタイプのオブジェクトを作成するか、関数に渡す必要があります。

コードには他にも問題があります。たとえば、内部のメモリ割り当てnewimgは少し疑わしいように見えますが(何を割り当てるつもりでしたか?)、それはこの質問の範囲外です。

于 2011-09-12T07:37:30.927 に答える
0

あなたはあなたのデザインについて別の考えを持つべきです。friend可能であれば機能を避けるのが最善です、

于 2011-09-12T07:10:57.160 に答える