C++ 继承和重写C+中的ostream运算符+;
我一直在试图找到答案,但似乎没有人和我有完全相同的问题C++ 继承和重写C+中的ostream运算符+;,c++,inheritance,operator-overloading,ostream,C++,Inheritance,Operator Overloading,Ostream,我一直在试图找到答案,但似乎没有人和我有完全相同的问题 我正在使用几个派生类。ostream操作符您不能实现操作符来从可以使用的基类调用方法: Base::method(/*parameters*/) 但是operator除了@Neil所说的之外,可能最好实现一个虚拟DoStream方法,因此您不需要向上转换: class Base{ private: virtual void DoStream(ostream& os){ // general stuff } publ
我正在使用几个派生类。ostream操作符您不能实现操作符来从可以使用的基类调用方法:
Base::method(/*parameters*/)
但是
operator除了@Neil所说的之外,可能最好实现一个虚拟DoStream
方法,因此您不需要向上转换:
class Base{
private:
virtual void DoStream(ostream& os){
// general stuff
}
public:
friend ostream& operator<<(ostream& os, Base& b){
b.DoStream(os);
return os;
}
};
class Derived : public Base{
private:
void DoStream(ostream& os){
Base::DoStream(os);
// derived specific stuff
}
};
类基{
私人:
虚拟void DoStream(ostream&os){
//一般材料
}
公众:
friend ostream&operator一个简单的方法是:
class Base
{
int FirstClassNumber;
public:
virtual void serialize(ostream& os) const
{
os << FirstClassNumber;
}
};
// Implement the stream operator for the base class.
// All it does is call erialize which is a virtual method that
// will call the most derived version.
ostream& operator << (ostream& os, const Base &base)
{
base.serialize(os);
return os;
}
class FirstDerived:public Base
{
int SecondClassNumber;
public:
// Override serialize to make it call the base version.
// Then output any local data.
virtual void serialize(ostream& os) const
{
Base::serialize(os);
os << SecondClassNumber;
}
};
类基
{
int FirstClassNumber;
公众:
虚拟空序列化(ostream&os)常量
{
osFirstDerived.cpp:
FirstDerived::operator << (ostream& os)
{
os <<
"The first Number is:
//This is the line that isn't working - someone else gave me this syntax
<< Base::operator<<
<< "The second number is"
<< SecondClassNumber;
}
FirstDerived::operator << (ostream& os)
{
os << "The first Number is:"
//This is the line that isn't working - someone else gave me this syntax
<< Base::operator<<
<< "The second number is"
<< SecondClassNumber;
}
FirstDerived::operator这里对Loki的答案做了一点修改。我没有使用虚拟序列化方法,而是使用虚拟to_string方法。我认为这可以在更多的上下文中重用,输出到ostream,这可能很有用
#include <iostream>
#include <string>
class Base
{
public:
Base();
virtual std::string to_string() const;
protected:
int first_class_number;
friend std::ostream& operator<<(std::ostream& os, const Base &base);
};
Base::Base()
: first_class_number(1)
{
}
std::string Base::to_string() const
{
return "Base: "+std::to_string(first_class_number);
}
class FirstDerived : public Base
{
public:
FirstDerived();
std::string to_string() const;
protected:
int second_class_number;
};
FirstDerived::FirstDerived()
: second_class_number(2)
{
}
std::string FirstDerived::to_string() const
{
return "FirstDerived: "+std::to_string(first_class_number)+" "+ std::to_string(second_class_number);
}
std::ostream& operator << (std::ostream& os, const Base &base)
{
os << base.to_string();
return os;
}
int main(int argc, const char *argv[])
{
std::cout << Base() << std::endl;
std::cout << FirstDerived() << std::endl;
return 0;
}
因此,我需要将其重新定义为'code'友元ostream&operator,那么我如何从子操作符调用父操作符?这正是OP试图避免的。静态的cast
。虽然很难看,但在这种情况下,虚拟的操作符我需要重新声明操作符“我认为问题最有可能…”-你观察到了什么症状?编译错误?行、消息?或不希望出现的运行时行为?如果是,你期望什么?Juraj:嗯,你在我写答案时编辑了它,所以我不知道。问题中的原始代码在基类中已经有一个类似于doStream的虚拟函数,奇怪地称为operator@Juraj,@Xeo-谢谢!请告诉我我是否正确-当我真的想打印一个派生实例时,我想要的行将是std::cout@Tony-你有什么建议?我不太理解你对Neil的评论。我真的是一个初学者。@BIU:好吧,Xeo和Martin的建议基本上和你的一样-根据我回答中给出的更正-除非他们避免使用运算符谢谢!我将仔细考虑你的建议以及@Juraj、@Xeo和其他评论者的建议,看看什么对我的程序最有效。最好的:)
os << x;
ostream & operator << ( ostream & os, const Child & c ) {
os << static_cast <const Parent &>( c );
// child stuff here
}
Base::method(/*parameters*/)
template<typename T>
void function(T const &t);
template<>
void function<Base>(Base const &t) {
// own implementation ...
}
template<>
void function<Derived>(Derived const &t) {
function<Base>(t);
// own implementation ...
}
class Base {
virtual void print(ostream &os) const {
// print self
}
};
class Derived {
virtual void print(ostream &os) const {
Base::print(os);
// print self
}
};
ostream &operator<< (ostream &os, Base const &b) {
b.print(os);
return os;
}
class Base{
private:
virtual void DoStream(ostream& os){
// general stuff
}
public:
friend ostream& operator<<(ostream& os, Base& b){
b.DoStream(os);
return os;
}
};
class Derived : public Base{
private:
void DoStream(ostream& os){
Base::DoStream(os);
// derived specific stuff
}
};
class Base
{
int FirstClassNumber;
public:
virtual void serialize(ostream& os) const
{
os << FirstClassNumber;
}
};
// Implement the stream operator for the base class.
// All it does is call erialize which is a virtual method that
// will call the most derived version.
ostream& operator << (ostream& os, const Base &base)
{
base.serialize(os);
return os;
}
class FirstDerived:public Base
{
int SecondClassNumber;
public:
// Override serialize to make it call the base version.
// Then output any local data.
virtual void serialize(ostream& os) const
{
Base::serialize(os);
os << SecondClassNumber;
}
};
FirstDerived::operator << (ostream& os)
{
os << "The first Number is:"
//This is the line that isn't working - someone else gave me this syntax
<< Base::operator<<
<< "The second number is"
<< SecondClassNumber;
}
os << "The first number is: "; // finish streaming statement with ";"
Base::operator<<(os); // separate statement to call this function...
os << "The second number is " << SecondClassNumber; // start streaming again
#include <iostream>
#include <string>
class Base
{
public:
Base();
virtual std::string to_string() const;
protected:
int first_class_number;
friend std::ostream& operator<<(std::ostream& os, const Base &base);
};
Base::Base()
: first_class_number(1)
{
}
std::string Base::to_string() const
{
return "Base: "+std::to_string(first_class_number);
}
class FirstDerived : public Base
{
public:
FirstDerived();
std::string to_string() const;
protected:
int second_class_number;
};
FirstDerived::FirstDerived()
: second_class_number(2)
{
}
std::string FirstDerived::to_string() const
{
return "FirstDerived: "+std::to_string(first_class_number)+" "+ std::to_string(second_class_number);
}
std::ostream& operator << (std::ostream& os, const Base &base)
{
os << base.to_string();
return os;
}
int main(int argc, const char *argv[])
{
std::cout << Base() << std::endl;
std::cout << FirstDerived() << std::endl;
return 0;
}
Base: 1
FirstDerived: 1 2