18.11 Printing inherited classes using operator<<
https://www.learncpp.com/cpp-tutorial/printing-inherited-classes-using-operator/
virtual function을 사용하는 다음 프로그램을 살펴보자
#include <iostream>
class Base
{
public:
virtual void print() const { std::cout << "Base"; }
};
class Derived : public Base
{
public:
void print() const override { std::cout << "Derived"; }
};
int main()
{
Derived d{};
Base& b{ d };
b.print(); // will call Derived::print()
return 0;
}
이제 우리는 b.print가 Derived::print()를 호출하는 것에 대해서 이해하고 있다
우리가 이를 std::cout과 연계를 하고 싶은데 현재 형태에서는 깔끔하게 이를 사용할 수 없다
#include <iostream>
int main()
{
Derived d{};
Base& b{ d };
std::cout << "b is a ";
b.print(); // messy, we have to break our print statement to call this function
std::cout << '\n';
return 0;
}
b.print()가 std::cout이 존재하므로 위처럼 써야한다
이상적으로는 다음과 같이 쓴는게 깔끔해보인다
std::cout << "b is a " << b << '\n'; // much better
The challenges with operator<<
operator<<에 일반적인 방법으로 overloading을 해보자
#include <iostream>
class Base
{
public:
virtual void print() const { std::cout << "Base"; }
friend std::ostream& operator<<(std::ostream& out, const Base& b)
{
out << "Base";
return out;
}
};
class Derived : public Base
{
public:
void print() const override { std::cout << "Derived"; }
friend std::ostream& operator<<(std::ostream& out, const Derived& d)
{
out << "Derived";
return out;
}
};
int main()
{
Base b{};
std::cout << b << '\n';
Derived d{};
std::cout << d << '\n';
return 0;
}
위의 프로그램을 실행하면 출력은 다음과 같다
Base
Derived
이를 Base ref에 Derived object를 넘겨서 출력해보자
int main()
{
Derived d{};
Base& bref{ d };
std::cout << bref << '\n';
return 0;
}
이때 출력은 다음과 같다
Base
이는 우리가 기대한 결과가 아니다.
Can we make Operator << virtual?
그렇다면 우리는 operatoro <<을 virtual로 할 수 있을까?
간단히 말하면 불가능하다
첫째, 오직 member function만이 virtualized 가 가능하다
둘째, 가능하다고 해도 operator의 정의를 보면 parameter가 각각 Base, Derived이다
그렇다면 어떻게 해야할까?
The solution
답은 의외로 간단하다
member function을 이용하는 것이다
#include <iostream>
class Base
{
public:
// Here's our overloaded operator<<
friend std::ostream& operator<<(std::ostream& out, const Base& b)
{
// Delegate printing responsibility for printing to member function print()
return b.print(out);
}
// We'll rely on member function print() to do the actual printing
// Because print is a normal member function, it can be virtualized
virtual std::ostream& print(std::ostream& out) const
{
out << "Base";
return out;
}
};
class Derived : public Base
{
public:
// Here's our override print function to handle the Derived case
std::ostream& print(std::ostream& out) const override
{
out << "Derived";
return out;
}
};
int main()
{
Base b{};
std::cout << b << '\n';
Derived d{};
std::cout << d << '\n'; // note that this works even with no operator<< that explicitly handles Derived objects
Base& bref{ d };
std::cout << bref << '\n';
return 0;
}
print라는 virtual member function을 이용해 operator<< 에서 실행되도록 해주면 된다
따라서 출력은 다음과 같다
Base
Derived
Derived
Author And Source
이 문제에 관하여(18.11 Printing inherited classes using operator<<), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ikmy0ung/18.11-Printing-inherited-classes-using-operator저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)