运算符<<和继承/组成

时间:2014-05-15 20:12:37

标签: c++ overloading operator-keyword

我发现自己在尝试重载运算符时遇到了一些麻烦<<正确。我已经搜索过有关它的其他问题,但没有一个答案似乎适合这个,所以这里是: 我有一个类(Register)存储另一个类的标本(Film的子类,它是抽象的)。重载运算符<< for Register应该通过ostream类将每个Film类型元素中存储的所有数据放在屏幕上。这是代码:

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

这些位于标题中,运算符&lt;&lt;在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的私有变量。所以我尝试将过载的运算符&lt;&lt;作为Register的成员,但编译器告诉我函数必须只接受一个参数。最后,如果我删除ostream&amp; os从参数中,它告诉我函数需要两个参数。所以我会对一个解决方案感兴趣,其中存储在pData中的信息可以通过运算符&lt;&lt;来有效地放在屏幕上。提前谢谢!

6 个答案:

答案 0 :(得分:2)

如果必须授予对operator<<实施(私人数据)的访问权限,则必须将Register声明为朋友:

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函数可以访问声明为朋友的类的所有私有(以及受保护和公共)数据。

C ++标准版n3337 § 11.3 / 1表示

  

班级的朋友是获得许可的职能或类别   使用类中的私有和受保护的成员名称。一类   通过朋友声明指定其朋友(如果有的话)。这样   声明给予朋友特殊的访问权限,但确实如此   不要成为朋友级别的指定朋友。

§ 11.3 / 2

  

声明一个类成为朋友意味着私有和   可以访问授予友谊的类的受保护成员   在友情的基本说明符和成员声明中   类。

答案 1 :(得分:1)

让你的operator<<成为班上的朋友。您可以阅读here

答案 2 :(得分:1)

您可以operator<< friend课程Register查看以下代码:

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

因此,operator<<可以访问Register个私有成员。

答案 3 :(得分:1)

要访问Register的私人成员,请operator<< friend function

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

答案 4 :(得分:1)

我在这样的项目中实现了OS-Operator:

XYZ.h文件

  

朋友std :: ostream&amp; operator&lt;&lt;(std :: ostream&amp; os,const Liwanze&amp; 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;

}

答案 5 :(得分:0)

或者如果您希望避免与不想要的朋友一起污染您的课程,请将格式推迟到注册的公共成员。

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函数遵从受保护的虚函数,则运算符&lt;&lt;即使在多线程环境中,也可以处理从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;
}