2013-05-09 8 views
6

はHERESに私のコードは:は、派生クラスから基底クラスで保護されたメンバにアクセスすることはできません

#include <iostream> 
#include <cmath> 
#include <sstream> 
using namespace std; 

class root 
{ 
    protected : 

      int size; 
      double *array; 

    public : 

     virtual ~root() {} 
     virtual root* add(const root&) = 0; 
     virtual root* sub(const root&) = 0; 
     virtual istream& in(istream&, root&) = 0; 
     virtual int getSize() const = 0; 
     virtual void setSize(int); 
}; 

class aa: public root 
{ 

    public : 

     aa(); 
     aa(int); 
     aa(const aa&); 
     root* add(const root& a); 
     root* sub(const root& a); 
     istream& in(istream&, root&){} 
     int getSize() const; 
     void setSize(int); 
}; 

class bb: public root 
{ 
public: 
    bb() { } 
    bb(const bb& b) { } 
    root* add(const root& a); 
    root* sub(const root& a); 
    istream& in(istream&, root&){} 
    int getSize() const{} 
    void setSize(int){} 
}; 

aa::aa() 
{ 
    size = 0; 
    array = NULL; 
} 

aa::aa(int nsize) 
{ 
    size = nsize; 
    array = new double[size+1]; 
    for(int i=0; i<size; i++) 
     array[i] = 0; 
} 

root* aa::add(const root& a) 
{ 
    for (int i=0; i<a.size; i++) 
     array[i] += a.array[i]; 
    return *this; 
} 

root* aa::sub(const root& a) 
{ 
} 

int aa::getSize() const 
{ 
    return size; 
} 

void aa::setSize(int nsize) 
{ 
    size = nsize; 
    array = new double[size+1]; 
    for(int i=0; i<size; i++) 
     array[i] = 0; 
} 

root* bb::add(const root& a) 
{ 
    return new bb(); 
} 

root* bb::sub(const root& a) 
{ 

} 

int main(int argc, char **argv) 
{ 
} 

私はsizeにアクセスするか、派生クラスでarray、私はちょうど私のコンパイラは、カント言うので:

/home/brian/Desktop/Temp/Untitled2.cpp||In member function ‘virtual root* aa::add(const root&)’:| 
/home/brian/Desktop/Temp/Untitled2.cpp|10|error: ‘int root::size’ is protected| 
/home/brian/Desktop/Temp/Untitled2.cpp|66|error: within this context| 
/home/brian/Desktop/Temp/Untitled2.cpp|11|error: ‘double* root::array’ is protected| 
/home/brian/Desktop/Temp/Untitled2.cpp|67|error: within this context| 
/home/brian/Desktop/Temp/Untitled2.cpp|68|error: cannot convert ‘aa’ to ‘root*’ in return| 
||=== Build finished: 5 errors, 0 warnings ===| 

保護されたメンバーは派生クラスではプライベートなので、大丈夫と思われますが、それはisntです。これを修正するには?

答えて

6

保護されたメンバーは派生クラスではプライベートなので、大丈夫と思われますが、そうではありません。

protectedデータメンバ(この場合aa)派生クラスBにより(この場合root、)基本クラスAから継承されたので、それがないアクセス可能な限り、それがアクセスされている通りでありますタイプがBaa)のオブジェクトです。ここでは、タイプAroot)のオブジェクトからアクセスされています

C++ 11標準のパラグラフ11.4/1パー
root* aa::add(const root& a) 
{ 
    for (int i=0; i<a.size; i++) 
    //    ^^^^^^ 
    //    Accessing size on an object of type `root`, not `aa`! 
     array[i] += a.array[i]; 
    return *this; 
} 

先に説明したもの以外に追加のアクセスチェック非静的データ メンバまたは非スタティックメンバ関数がその命名クラス(11.2)の保護されたメンバである場合に適用されます。 と記載されているように、保護されたメンバーへのアクセスは、友人または一部の クラスCのメンバーで発生するため、アクセスが許可されます。アクセスがメンバ(5.3.1)へのポインタを形成する場合、ネストされた名前指定子はCまたはCから派生した クラスを表すものとする。他のすべてのアクセスには(おそらく暗黙の)オブジェクト式(5.2.5) 。これを解決するには - [エンド例えば

class B { 
protected: 
    int i; 
    static int j; 
}; 
class D1 : public B { 
}; 
class D2 : public B { 
    // ... 
    void mem(B*,D1*); 
}; 

void D2::mem(B* pb, D1* p1) { 
    pb->i = 1; // ill-formed 
    p1->i = 2; // ill-formed 
    // ... 
    i = 3; // OK (access through this) 
    B::i = 4; // OK (access through this, qualification ignored) 
    j = 5; // OK (because j refers to static member) 
    B::j = 6; // OK (because B::j refers to static member) 
} 

例]

この場合、オブジェクト表現の クラスは、CまたはCから派生したクラスでなければなりませんパブリックセッター/ゲッターを提供する必要があります。あなたは既にgetSize()機能を持っているので、代わりにこれを書いている:

for (int i=0; i<a.size; i++) 
//    ^^^^^^ 

あなたはこの記述することができます。同様に

for (int i=0; i<a.getSize(); i++) 
//    ^^^^^^^^^^^ 

を、あなたはN-の値を設定/取得するための機能を提供する必要がありますarrayの番目の要素は、次のように書くことができるように:

array[i] += a.get_at(i); 

お知らせを、+=の左側の式がOKであることを、理由はthisによってアクセスされています(上記のC++ 11標準の例も参照してください)。

+0

ありがとう:)だから、これを修正する方法はありますか? –

+2

@BrianBrown: 'root'で' size() 'と呼ばれる' public'ゲッター関数を使うことができますか? –

+0

私はそれを 'root'で既に定義しましたが、その純粋な仮想(それは間違っていますか?)。しかし配列についてはどうですか? –

関連する問題