簡體   English   中英

無法從派生類訪問基類中的受保護成員

[英]Can't access protected member in base class from derived class

繼承我的代碼:

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

當我想在派生類中訪問sizearray時,我只是因為我的編譯器說:

/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 ===|

我讀到受保護的成員在派生類中是私有的,所以它似乎沒問題,但它不是。 如何解決這個問題?

我讀到受保護的成員在派生類中是私有的,所以它似乎沒問題,但它不是。

這不是因為派生類B (在本例中為aa )繼承自基類A (在本例中為root )的protected數據成員是可訪問的,只要它在類型B的對象上被訪問aa )。 在這里,您通過Aroot )類型的對象訪問它:

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

根據C ++ 11標准的第11.4 / 1段:

當非靜態數據成員或非靜態成員函數是其命名類的受保護成員時,將應用超出第11章中所述之外的其他訪問檢查(11.2)。 如前所述,授予對受保護成員的訪問權限,因為引用發生在某個C類的朋友或成員中 如果訪問要形成指向成員的指針(5.3.1),則嵌套名稱說明符應表示C或從C派生的類。 所有其他訪問都涉及(可能是隱式的)對象表達式(5.2.5)。 在這種情況下,對象表達式的類應為C或從C派生的類。 [ 示例:

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

- 結束例子 ]

要解決此問題,您需要提供公共setter / getter。 你已經有了一個getSize()函數,所以不要寫這個:

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

你可以這樣寫:

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

同樣,您必須提供獲取/設置array第n個元素值的函數,以便您可以編寫:

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

請注意, +=左側的表達式是正確的,因為正在通過this訪問array (另請參閱上面的C ++ 11標准示例)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM