I have a code sample which behaves strange for me. With inheritance in C++ one can declare array of pointers to base class with pure virtual function (aka Interface) and call derived member functions over it;
class Base {
public:
virtual void call() = 0;
};
class Derived1 : public Base {
public:
void call() override final {
std::wcout << L"derived 1" << std::endl;
}
};
class Derived2 : public Base {
public:
void call() override final {
std::wcout << L"derived 2" << std::endl;
}
};
int main() {
Base* b[2];
b[0] = new Derived1;
b[1] = new Derived2;
for (int i = 0; i < 2; ++i) {
b[i]->call();
}
return 0;
}
Which gives:
derived 1
derived 2
just as planned. But when I trying following code sample it makes me a little bit confusing:
class Base {
public:
virtual Base* print() = 0;
template<typename T>
Base& operator<<(const T &_val) {
std::wcout << L" d0 << " << _val;
return *this;
}
};
class Derived1 : public Base {
public:
Derived1* print() override final {
return this;
}
template<typename T>
Derived1& operator<<(const T &_val) {
std::wcout << L" d1 << " << _val;
return *this;
}
};
class Derived2 : public Base {
public:
Derived2* print() override final {
return this;
}
template<typename T>
Derived2& operator<<(const T &_val) {
std::wcout << L" d2 << " << _val;
return *this;
}
};
int main() {
Base* b[2];
b[0] = new Derived1;
b[1] = new Derived2;
for (int i = 0; i < 2; ++i) {
std::wcout << typeid(*b[i]->print()).name();
*b[i]->print() << 7 << 7;
std::wcout << std::endl;
}
return 0;
}
The output is:
8Derived1 d0 << 7 d0 << 7
8Derived2 d0 << 7 d0 << 7
Which means that only Base's operator<< was called (But prints() return types seems to be correst).
The question is why it behaves like so?
UPD:
Seems like I need static polymorphism here without virtual functions. But how could this be achieved? I need an array of different Derived classes to perform actions in operator<< on any data type. UPD2:
Looks like I can use type erasure for operator<< parameter. But how can I restore type inside derived's operator<< then? (For example if I suggest to use boost::any)