1

これはより大きなプロジェクトの一部です。

基本的に、プログラムを管理するためのクラス「X」があり、そのクラスにはクラス「Y」からのオブジェクトへのポインタの配列があり、クラス「Y」のオブジェクトにアクセスする必要がある別のクラス「Z」があります。たとえば、プリント。

「このスコープで宣言されていません」というエラーが表示されます

クラス「Y」のクラス「Z」の友達を作ろうとしましたが、うまくいきません。

私はこの問題を実証するためのコードを書きました:

#include <iostream>
using namespace std;

class BaseClass;
class OtherClass;
class Manager;

class BaseClass
{
    friend class OtherClass;

    public:
        BaseClass(){}
        void setNum(int num){_num = num;}
        int getNum(){return _num;}

    private:
        int _num;
};

class OtherClass
{
    public:
        OtherClass(){}
        void print(){
        cout << _bc[0]->getNum() << " " << _bc[1]->getNum() << endl;
        }
};

class Manager
{
    friend class OtherClass;
    public:
        Manager(){}

        void run(){
            _bc = new BaseClass*[10];

            _bc[0]->setNum(20);
            _bc[1]->setNum(30);

           _oc.print();
        }

    private:
        BaseClass ** _bc;
        OtherClass _oc;
};


int main()
{
    Manager m;
    m.run();

    return 0;
}

たぶんこれはとても簡単ですが、ここでは遅く、私は眠いので、寝る前にこの問題を解決したいと思います。

編集済み:私のプロジェクトにはクラスマネージャーがあり、そのクラスにはクライアント注文へのポインターの配列があります。クラスオーダーは、とりわけクライアントを受け取ります。そのため、オーダーに挿入するクライアントを選択するために、そのポインターの配列にアクセスする必要があります。

4

3 に答える 3

1

まず第一に、のポインタ型へのポインタは必要ないようです_bc。クラスで配列を定義するだけでOtherClass(またはstd::vector実際にはanの方が優れています)、のを作成Managerします。そしてもちろん、クラスから宣言を削除することができます。friendOtherClassfriendBaseClassManager

class OtherClass
{
  public:
    OtherClass(){}
    void print(){
      cout << _bc[0].getNum() << " " << _bc[1].getNum() << endl;
    }   
  private:
    BaseClass * _bc;
  friend class Manager;
};

class Manager
{
  public:
  Manager(){}

  void run(){
    _oc._bc = new BaseClass[10];
    _oc._bc[0].setNum(20);
    _oc._bc[1].setNum(30);

    _oc.print();
  }

  private:
  OtherClass _oc;
};
于 2012-12-26T01:39:06.360 に答える
1

C ++には、アクセシビリティスコープという2つの異なる概念があります。あなたの質問から、あなたはこれらの2つの概念がいくらか混同されているように見えます(それらは互いに非常に近いので、私はあなたを責めません)。

アクセシビリティは、、などによって制御され、private「友情」を通じて追加で付与することができます。一方、スコープは、アクセスされる変数と関数の配置によって制御されます。publicprotected

クラスのメンバーが別のクラスのメンバーにアクセスするには、他のメンバーがスコープ内にある必要があります。また、アクセス可能である必要があります。が宣言されているクラスの、から_bcアクセスしようとしているようです。友情は問題のアクセシビリティの部分を解決しますが、スコープの部分には対処しません。クラスのインスタンスメンバーにアクセスするには、オブジェクトへの何らかの参照が必要です。参照を取得する方法はたくさんあります。たとえば、のコンストラクターでへの参照を渡し、それをプライベート変数に格納して、次のようにアクセスできます。OtherClassfriend_bcOtherClass_bcManagerManagerManagerOtherClass_bc

class OtherClass {
    Manager &_m;
public:
    OtherClass(Manager &m) : _m(m) {}
    void print(){
        cout << _m._bc[0]->getNum() << " " << _m._bc[1]->getNum() << endl;
    }
};

これは、スコープの問題を解決する唯一の方法です。他の方法にはManager、のパラメータとして渡す、ポインタを作成する、OtherClass::print静的にするなどがあります。正確な方法は、要件によって異なります。_m_bc

于 2012-12-26T01:51:58.233 に答える
0

BaseClassインスタンスを正しく割り当てなかったため、コードをコンパイルしても機能しませんでした。さらに、rawの使用new[]は非常に心配です。代わりにstd::vector<BaseClass>またはを使用することを検討してください。std::vector<std::unique_ptr<BaseClass>>

OtherClassでは、Managerポインターまたは参照を取得し、そのprint()メンバーの定義を遅らせる必要があります。コンパイラーは、スコープ内OtherClass::printに何も呼び出されていないことを通知するのに完全に正しいです。_bcインスタンスを明示的に渡す必要がありManagerます。

于 2012-12-26T01:36:22.193 に答える