簡體   English   中英

運算符<<和繼承/組成

[英]Operator << and inheritance/composition

我發現自己嘗試正確重載operator <<有點麻煩。 我搜索了有關此問題的其他問題,但是似乎沒有一個答案適合這個問題,因此這里是:我有一個類(Register),它存儲另一個類的樣本(Film的子類,它是抽象的)。 重載的<<操作符應通過ostream類將存儲在每個Film類型元素中的所有數據通過ostream類放置在屏幕上。以下是代碼:

class Register{                                             
    private:
    int elementNum;
    Film* pData;
    };
    ostream &operator<<(ostream & os,const Register &v);

這些位於頭文件中,運算符<<在cpp中:

ostream &operator<<(ostream & os,const Register &v){
    for(int i=0;i<v.elementNum;i++){
os<<v.pData[i].print()<<endl;
}
return os;
    }

問題是,這樣我無法訪問Register的私有變量。 因此,我嘗試將重載的運算符<<作為Register的成員,但是編譯器告訴我該函數必須僅接受一個參數。 最后,如果我從參數中刪除ostream&os,它告訴我該函數需要兩個參數。 因此,我對一種解決方案感興趣,該解決方案可以使用運算符<<將pData中存儲的信息有效地顯示在屏幕上。 提前致謝!

如果必須授予對Register實現的訪問權限(私有數據),則必須將operator<<聲明為朋友:

class Register{                                             
    private:
    //...
    friend std::ostream &operator<<( std::ostream & os,const Register &v);
};

std::ostream &operator<<( std::ostream & os,const Register &v) {
    for( int i=0; i<v.elementNum; i++){
        os << v.pData[i].print() << std::endl;
    }
    return os;
}

Friend函數可以訪問聲明為Friends的類的所有私有(以及受保護的和Public的)數據。

C ++標准n3337§11.3 / 1說

友人

類的朋友是被授予使用該類的私有和受保護成員名稱的權限的函數或類。 類通過朋友聲明來指定其朋友(如果有)。 此類聲明為朋友提供了特殊的訪問權限,但它們並未使被提名的朋友成為朋友班的成員。

§11.3 / 2

將一個類聲明為朋友意味着可以從該類的基礎說明符和成員聲明中訪問該類授予友誼的私有成員和受保護成員的名稱。

讓您的operator<<成為班上的朋友。 您可以在這里閱讀。

您可以將operator<<成為類Registerfriend ,請參見下面的代碼:

class Register{                                             
    private:
    friend ostream &operator<<(ostream & os,const Register &v);
    int elementNum;
    Film* pData;
};

因此, operator<<將有權訪問類Register私有成員。

要訪問Register的私有成員,請使operator<<friend function

class Register{                                             
    private:
    int elementNum;
    Film* pData;
    friend ostream &operator<<(ostream & os,const Register &v);
};

我在這樣的項目中實現了OS-Operator:

XYZ.h文件

朋友std :: ostream&運算符<<(std :: ostream&os,const Liwanze&arg);

XYZ.cpp文件

std::ostream& operator<<(std::ostream& os, const Liwanze& arg) {
string area = "";
if (arg.loc == 1)
    area = "Buxtehude";
if (arg.loc == 2)
    area = "Bangladesch";
if (arg.loc == 3)
    area = "Zimbabwe";
if (arg.loc == 4)
    area = "Bronx";
os << arg.name << " [" << area << "] ";
return os;

}

或者,如果您希望避免與不需要的朋友一起污染您的班級,請將格式推遲到Register的公共成員處。

class Register{                                             
public:
    void writeTo(std::ostream& os) const {
        for( int i=0; i<elementNum; i++){
            os << pData[i].print() << std::endl;
        }
    }
private:
    //...
};

std::ostream &operator<<( std::ostream & os,const Register &v) {
    v.writeTo(os);
    return os;
}

如果使writeTo函數服從受保護的虛函數,則即使在多線程環境中,operator <<也將對從Register派生的任何東西起作用。

class Register{                                             
public:
    // public non-polymorphic interface...
    void writeTo(std::ostream& os) const {
        os << "any header information\n" << endl;
        std::lock_guard<std::mutex> myLock(_myInternalMutex);  // in MT environment
        handleWriteTo(os);  // defer to protected polymorphic implementation
    }

protected:
    virtual void handleWriteTo(std::ostream& os) const {
        for( int i=0; i<elementNum; i++){
            os << pData[i].print() << std::endl;
        }
    }
private:
    //...
};

std::ostream &operator<<( std::ostream & os,const Register &v) {
    v.writeTo(os);
    return os;
}

暫無
暫無

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

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