I am learning C++. I have a base class, Base, and its derived class, Derived. And they are push_back into std::vector<Base*> vec. Assuming vec[0] == &Base and vec[1] == &Derived, I can switch function for vec[0] and vec[1] without virtual function. The code is at the end of this question. Is there better way to do it without virtual function? I want pure data classes and I want to add non-member functions to modify them to avoid modifying code of data classes. Thank you very much.
class TypeInterface {
public:
virtual int type(void) = 0;
virtual ~TypeInterface() {}
};
class Base : public TypeInterface {
public:
static constexpr int type_ = 1;
virtual int type(void) {
return type_;
}
virtual ~Base() {}
};
class Derived : public Base {
public:
static constexpr int type_ = 10;
virtual int type(void) {
return type_;
}
virtual ~Derived() {};
};
void Function(Base* ptr) {
std::cout << "function for Base" << std::endl;
}
void Function(Derived* ptr) {
std::cout << "function for Derived" << std::endl;
}
void SwitchFunction(int type, void* ptr) {
switch (type) {
case 1: {
Base* original_type_ptr = static_cast<Base*>(ptr);
Function(original_type_ptr);
break;
}
case 10: {
Derived* original_type_ptr = static_cast<Derived*>(ptr);
Function(original_type_ptr);
break;
}
default:
std::cout << "invalid type(=" << type << ")" << std::endl;
}
}
void test_function_selecter(void) {
Base b;
Derived d;
std::vector<Base*> vec;
vec.push_back(&b);
vec.push_back(&d);
for (auto e: vec) {
SwitchFunction(e->type(), e);
}
}
You do not need 'type_', or 'int type(void)' instead use 'typeid'
void SwitchFunction(Base* ptr)
{
auto&& type = typeid(*ptr);
if (type == typeid(Base))
Function(dynamic_cast<Base*>(ptr));
else if (type == typeid(Derived))
Function(dynamic_cast<Derived*>(ptr));
else std::cout << "invalid type(=" << type.name() << ")" << std::endl;
}
Unfortunately this probably does not answer your question properly as it requires 'Base' to have a virtual function (such as a destructor, whish is generally recommended to be virtual whenever your type is involved in hierarchies)
Related
as the below code, I don't want so many "if else"
class A
{
public:
void f0()
{
cout << "f0" << endl;
}
void f1()
{
cout << "f1" << endl;
}
void f2()
{
cout << "f2" << endl;
}
//..... more functions fn()...
};
class B
{
public:
void f(int n)
{
//vector< function<void()> > f_v {obj_a.f0, obj_a.f1, obj_a.f2}; //this usage is not correct
if (n == 0)
obj_a.f0();
else if (n == 1)
obj_a.f1();
else if (n == 2)
obj_a.f2();
//.....more else if here
}
private:
A obj_a;
};
I want to create a vector and use std::function to avoid using so many if-else , like vector< function<void()> > f_v {obj_a.f0, obj_a.f1, obj_a.f2}; but it doesn't work, maybe the usage of std::function is not very correct. How should I do? Or is there any other good way to solve the problem of if else, I think use so many switch-case is also not very elegant :)
update:
Some answers have already solve my problem about the usage of std::function in my earlier code;
More generally, considering the below code, if the member functons A::f1(), A::f2().... have different return types, but still have some connection that they derived from a same base class , what's the good way to implement the logic of if else in B::f()?
class Base
{
public:
virtual ~Base()=default;
};
class D1 : public Base
{
public:
};
class D2 : public Base
{
public:
};
class D3 : public Base
{
public:
};
// ....maybe more class derived form Base
class A
{
public:
D1* f0()
{
cout << "f0" << endl;
return &d1;
}
D2* f1()
{
cout << "f1" << endl;
return &d2;
}
D3* f2()
{
cout << "f2" << endl;
return &d3;
}
//more fn()....
private:
D1 d1;
D2 d2;
D3 d3;
//.....
};
class B
{
public:
void f(int n)
{
if (n == 0)
obj_a.f0();
else if (n == 1)
obj_a.f1();
else if (n == 2)
obj_a.f2();
//.....more else if here
}
private:
A obj_a;
};
You can use std::function with a lambda wrapper,
vector<function<void()>> f_v {[this]() { obj_a.f0(); },
[this]() { obj_a.f1(); },
[this]() { obj_a.f2(); }};
f_v[n]();
or use pointer-to-members directly,
vector<void (A::*)()> f_v { &A::f0, &A::f1, &A::f2 };
(obj_a.*f_v[n])();
If you are aiming at speed and you know the number of methods, avoid using std::vector for the extra indirection. Use std::array as it will hit cache with the current object.
For this simple case, you don't necessarily need to use std::function, which is a very heavy object to call. You can use pointers to members like this:
#include <iostream>
#include <array>
using namespace std;
class A
{
public:
void f0()
{
cout << "f0" << endl;
}
void f1()
{
cout << "f1" << endl;
}
void f2()
{
cout << "f2" << endl;
}
//.....
};
class B
{
public:
B() {
fn[0] = &A::f0;
fn[1] = &A::f1;
fn[2] = &A::f2;
}
void f(int n)
{
((obj_a).*(fn[n]))();
}
private:
using Fn = void (A::*)();
std::array<Fn,3> fn;
A obj_a;
};
Code: https://godbolt.org/z/z4KqKvn99
Your approach seems correct. You just need to std::bind those member functions like
class B{
std::vector <std::function <void()>> m_vec_functs;
...
B(const A& a)
{
m_vec_functs.push_back(std::bind(&A::f0, a));
m_vec_functs.push_back(std::bind(&A::f1, a));
}
void f(unsigned int n)
{
m_vec_functs[n];
}
...
};
Then you can access each individual function by its index, knowing their order.
Can somebody explain my why my factory function is correct? Is unique_ptr doing dynamic casts by default? Why does the return type not have to be the same as the factory function type?
#include <exception>
#include <iostream>
#include <memory>
struct Animal
{
virtual void makeSound() { std::cout << "(...)" << std::endl; }
};
struct Cat : public Animal
{
virtual void makeSound() { std::cout << "Meaw!" << std::endl; }
};
struct Dog: public Animal
{
virtual void makeSound() { std::cout << "Woof!" << std::endl; }
};
struct ConfusedCat : public Cat
{
virtual void makeSound() { std::cout << "Moooooh!" << std::endl; }
};
// Why is this factory function allowed like this?
std::unique_ptr<Animal> factory(const int i)
{
if (i == 1)
return std::unique_ptr<Cat>(new Cat());
else if (i == 2)
return std::unique_ptr<ConfusedCat>(new ConfusedCat());
else if (i == 3)
return std::unique_ptr<Dog>(new Dog());
else
return std::unique_ptr<Animal>(new Animal());
}
int main()
{
try
{
auto animal0 = factory(0);
auto animal1 = factory(1);
auto animal2 = factory(2);
auto animal3 = factory(3);
animal0->makeSound();
animal1->makeSound();
animal2->makeSound();
animal3->makeSound();
}
catch ( std::exception &e )
{
std::cout << e.what() << std::endl;
return 1;
}
return 0;
}
In C++ derived to public base pointer conversion is implicit, no cast is required.
The same holds true for all standard and boost smart pointers.
See overload 6 on std::unique_ptr::unique_ptr:
std::unique_ptr<Derived> is implicitly convertible to std::unique_ptr<Base> through the overload (6)
At the moment I'm dealing with a delightful legacy code class implementing polymorphism by switch-case:
class LegacyClass {
public:
enum InitType {TYPE_A, TYPE_B};
void init(InitType type) {m_type=type;}
int foo() {
if (m_type==TYPE_A)
{
/* ...A-specific work... */
return 1;
}
// else, TYPE_B:
/* ...B-specific work... */
return 2;
}
/** Lots more functions like this **/
private:
InitType m_type;
};
I'd like to refactor this to proper polymorphism, e.g.:
class RefactoredClass {
public:
virtual ~RefactoredClass(){}
virtual int foo()=0;
};
class Class_ImplA : public RefactoredClass {
public:
virtual ~Class_ImplA(){}
int foo() {
/* ...A-specific work... */
return 1;
}
};
class Class_ImplB : public RefactoredClass {
public:
virtual ~Class_ImplB(){}
int foo() {
/* ...B-specific work... */
return 2;
}
};
Unfortunately, I have one crucial problem: due to optimization and architectural considerations, within a primary use of LegacyClass, I cannot use dynamic allocation; the instance is a member of a different class by composition:
class BigImportantClass{
/* ... */
private:
LegacyClass m_legacy;
}
(In this example, BigImportantClass may be dynamically allocated, but the allocation needs to be in one continuous virtual segment, and a single new() call; I can't make further calls to new() in the BigImportantClass ctor or in subsequent initialization methods.)
Is there a good way to initialize a concrete implementation, polymorphically, without using new()?
My own progress so far: What I can do is provide a char[] buffer as a member of BigImportantClass, and somehow initialize a concrete member of RefactoredClass in that memory. The buffer would be large enough to accommodate all implementations of RefactoredClass. However, I do not know how to do this safely. I know the placement-new syntax, but I'm new to dealing with alignment (hence, warned off by the C++-FAQ...), and aligning generically for all concrete implementations of the RefactoredClass interface sounds daunting. Is this the way to go? Or do I have any other options?
Here's some code... just doing the obvious things. I don't use C++11's new union features, which might actually be a more structured way to ensure appropriate alignment and size and clean up the code.
#include <iostream>
template <size_t A, size_t B>
struct max
{
static const size_t value = A > B ? A : B;
};
class X
{
public:
X(char x) { construct(x); }
X(const X& rhs)
{ rhs.interface().copy_construct_at_address(this); }
~X() { interface().~Interface(); }
X& operator=(const X& rhs)
{
// warning - not exception safe
interface().~Interface();
rhs.interface().copy_construct_at_address(this);
return *this;
}
struct Interface
{
virtual ~Interface() { }
virtual void f(int) = 0;
virtual void copy_construct_at_address(void*) const = 0;
};
Interface& interface()
{ return reinterpret_cast<Interface&>(data_); }
const Interface& interface() const
{ return reinterpret_cast<const Interface&>(data_); }
// for convenience use of virtual members...
void f(int x) { interface().f(x); }
private:
void construct(char x)
{
if (x == 'A') new (data_) Impl_A();
else if (x == 'B') new (data_) Impl_B();
}
struct Impl_A : Interface
{
Impl_A() : n_(10) { std::cout << "Impl_A(this " << this << ")\n"; }
~Impl_A() { std::cout << "~Impl_A(this " << this << ")\n"; }
void f(int x)
{ std::cout << "Impl_A::f(x " << x << ") n_ " << n_;
n_ += x / 3;
std::cout << " -> " << n_ << '\n'; }
void copy_construct_at_address(void* p) const { new (p) Impl_A(*this); }
int n_;
};
struct Impl_B : Interface
{
Impl_B() : n_(20) { std::cout << "Impl_B(this " << this << ")\n"; }
~Impl_B() { std::cout << "~Impl_B(this " << this << ")\n"; }
void f(int x)
{ std::cout << "Impl_B::f(x " << x << ") n_ " << n_;
n_ += x / 3.0;
std::cout << " -> " << n_ << '\n'; }
void copy_construct_at_address(void* p) const { new (p) Impl_B(*this); }
double n_;
};
union
{
double align_;
char data_[max<sizeof Impl_A, sizeof Impl_B>::value];
};
};
int main()
{
{
X a('A');
a.f(5);
X b('B');
b.f(5);
X x2(b);
x2.f(6);
x2 = a;
x2.f(7);
}
}
Output (with my comments):
Impl_A(this 0018FF24)
Impl_A::f(x 5) n_ 10 -> 11
Impl_B(this 0018FF04)
Impl_B::f(x 5) n_ 20 -> 21.6667
Impl_B::f(x 6) n_ 21.6667 -> 23.6667
~Impl_B(this 0018FF14) // x2 = a morphs type
Impl_A::f(x 7) n_ 11 -> 13 // x2 value 11 copied per a's above
~Impl_A(this 0018FF14)
~Impl_B(this 0018FF04)
~Impl_A(this 0018FF24)
I implemented this using C++11 unions. This code seems to work under g++ 4.8.2, but it requires the -std=gnu++11 or -std=c++11 flags.
#include <iostream>
class RefactoredClass {
public:
virtual ~RefactoredClass() { }; // Linking error if this is pure. Why?
virtual int foo() = 0;
};
class RefactorA : RefactoredClass {
double data1, data2, data3, data4;
public:
int foo() { return 1; }
~RefactorA() { std::cout << "Destroying RefactorA" << std::endl; }
};
class RefactorB : RefactoredClass {
int data;
public:
int foo () { return 2; }
~RefactorB() { std::cout << "Destroying RefactorB" << std::endl; }
};
// You may need to manually create copy, move, &ct operators for this.
// Requires C++11
union LegacyClass {
RefactorA refA;
RefactorB refB;
LegacyClass(char type) {
switch (type) {
case 'A':
new(this) RefactorA;
break;
case 'B':
new(this) RefactorB;
break;
default:
// Rut-row
break;
}
}
RefactoredClass * AsRefactoredClass() { return (RefactoredClass *)this; }
int foo() { return AsRefactoredClass()->foo(); }
~LegacyClass() { AsRefactoredClass()->~RefactoredClass(); }
};
int main (void) {
LegacyClass A('A');
LegacyClass B('B');
std::cout << A.foo() << std::endl;
std::cout << B.foo() << std::endl;
return 0;
}
Somebody should have made an answer by now...so here's mine.
I'd recommend using a union of char array and one of the biggest integer types:
union {
char refactored_class_buffer[ sizeof RefactoredClass ];
long long refactored_class_buffer_aligner;
};
I also strongly recommend putting an assert or even an if(check) throw; into your factory so that you never, ever, exceed the size of your buffer.
If the data is the same for each case, and you're only changing behaviuor, you don't need to allocate in your core - this is basically a strategy pattern using singleton strategies. You end up using polymorphism in your logic, but not in your data.
class FooStrategy() {
virtual int foo(RefactoredClass& v)=0;
}
class RefactoredClass {
int foo() {
return this.fooStrategy(*this);
}
FooStrategy * fooStrategy;
};
class FooStrategyA : public FooStrategy {
//Use whichever singleton pattern you're happy with.
static FooStrategyA* instance() {
static FooStrategyA fooStrategy;
return &fooStrategy;
}
int foo(RefactoredClass& v) {
//Do something with v's data
}
}
//Same for FooStrategyB
Then when you create a RefactoredClass you set its fooStrategy to FooStrategyA::instance().
It's hard to explain exactly what I want to do here, but I have a base class and two classes which inherit this base class. Both classes which inherit it have their own unique members. I want to be able to pass both to a method, and have that method detect which it is, then access their unique members. I can't assume there will only be two classes which inherit it, so i'm looking for something of a more general solution.
Here is an example of what I'd like to do:
#include <iostream>
class Base {
public:
int _type;
Base() { }
};
class First : public Base {
public:
int _first_only;
First() { }
};
class Second : public Base {
public:
int _second_only;
Second() { }
};
void test (Base b) {
std::cout << "Type: " << b._type << std::endl;
if(b._type==1) {
std::cout << "First\n";
// Want to be able to do this
std::cout << "Val: " << (First)b._first_only << std::endl;
} else if(b._type==2) {
std::cout << "Second\n";
// And this
std::cout << "Val: " << (Second)b._second_only << std::endl;
}
}
int main() {
First f;
f._first_only=1;
f._type=1;
Second s;
s._type=2;
s._second_only=2;
test(f);
test(s);
}
This is similar to others answers:
You can write polymorphic classes to get this behavior using virtual functions.
Pass the Dervied class objects either by pointer or by reference to get polymorphic behaviour. Otherwise it will lead to object slicing. Your test() function leads to object slicing.
This code may also help you. You can see that there are different ways to print the type. I used GetBaseType(), GetDerivedType() and GetType(). Among these GetType() method is convenient for you case. There are two constructors for convenience. Constructors allow to initialize data members.
class Base {
private:
int _type;
public:
Base(int type) : _type(type) { }
int GetBaseType() { return _type; }
virtual int GetDerivedType() = 0;
virtual int GetType() { return _type; }
};
class First : public Base {
private:
int _first_only;
public:
First() : Base(1), _first_only(1) { }
First(int first_only) : Base(first_only), _first_only(first_only) { }
int GetDerivedType() { return _first_only; }
virtual int GetType() { return _first_only; }
};
class Second : public Base {
private:
int _second_only;
public:
Second() : Base(2), _second_only(2) { }
Second(int second_only) : Base(second_only), _second_only(second_only) { }
int GetDerivedType() { return _second_only; }
virtual int GetType() { return _second_only; }
};
void test (Base &b) {
std::cout << "Type: " << b.GetBaseType() << std::endl;
std::cout << "Type: " << b.Base::GetType() << std::endl;
std::cout << "Dervied type: \n";
std::cout << "Val: " << b.GetDerivedType() << std::endl;
std::cout << "Val: " << b.GetType() << std::endl;
}
int main() {
First f(1);
Second s(2);
test(f);
test(s);
First f1;
Second s1;
test(f1);
test(s1);
}
Either declare a virtual function in Base
Move the common members types from First and Second into Base.
For your specific problem, 2nd option is better:
class Base {
public:
int _member; // have getter() method, if '_member' is private
Base() { }
};
Inside, test():
void test (Base &b) { // <--- practice to pass by reference if copy is not needed
// use b._member;
};
Your code does not work polymorphically, because you are passing the function-parameter by value, which results in slicing.
If you have a method that does different things for different types, consider overloading it for each of these types.
Three things I'd do:
In general switching on type codes is not considered good object oriented design: Instead pull the switched code into the classes.
I'd also set up the type tags in the constructor of the specific classes.
And as others have mentioned you need to pass the argument by reference to avoid slicing.
Here's what the code would look like:
#include <iostream>
class Base {
public:
int _type;
Base() { }
virtual void print_to_stream( std::ostream & os ) const =0;
};
class First : public Base {
public:
int _first_only;
First() { _type =1; }
void print_to_stream( std::ostream & os ) const
{
os<<"First\n";
os<<"Val: " << _first_only << std::endl;
}
};
class Second : public Base {
public:
int _second_only;
Second() { _type=2; }
void print_to_stream( std::ostream & os ) const
{
os << "Second\n";
os << "Val: " << _second_only << std::endl;
}
};
void test (Base & b)
{
std::cout << "Type: " << b._type << std::endl;
b.print_to_stream( std::cout );
}
int main() {
First f;
f._first_only=1;
Second s;
s._second_only=2;
test(f);
test(s);
}
I have an existing application in C++ with a custom ArrayBase class that manages storage and access to a contiguously allocated region of memory. I have a separate ItrBase class that is used to access data in that ArrayBase. ArrayBase has a createItr() function that currently returns an ItrBase object.
I need to extend ArrayBase to use multiple memory allocations instead of one contiguous one. I have created an EnhancedArray class to do that. For this EnhancedArray to be compatible with the existing application, it's createItr() function must return something that works with the new multiple memory allocations.
So, I have created a derived EnhanceItr class to do this.
My problem is I can't figure out a way for hundreds of code occurrences like this:
ItrBase anIterator = anArray.createItr();
...
double x = anIterator.getData();
to use the EhancedItr's getData() function when anArray is an EnhancedArray.
Here is a simple application illustrating my basic arrangement.
#include <iostream>
using namespace std;
class ItrBase {
public:
ItrBase() { cout << "ItrBase constructor.\n"; };
~ItrBase() { cout << "ItrBase destructor.\n"; };
virtual int vfunc() {return 1;};
};
class EnhancedItr : public ItrBase {
public:
EnhancedItr() { cout << "EnhancedItr constructor.\n"; };
~EnhancedItr() { cout << "EnhancedItr destructor.\n"; };
int vfunc() {return 0;};
};
class ArrayBase {
public:
ArrayBase() { cout << "ArrayBase constructor.\n"; };
~ArrayBase() { cout << "ArrayBase destructor.\n"; };
virtual ItrBase & createItr() {cout << "in AB's createItr()\n"; return *new ItrBase(); };
};
class EnhancedArray : public ArrayBase {
public:
EnhancedArray() { cout << "EnhancedArray constructor.\n"; };
~EnhancedArray() { cout << "EnhancedArray destructor.\n"; };
EnhancedItr & createItr() {cout << "in EA's createItr()\n"; return *new EnhancedItr(); };
};
int main()
{
ArrayBase ab;
EnhancedArray ea;
ItrBase itr = ab.createItr();
ItrBase eitr = ea.createItr(); //EnhancedItr assigned to ItrBase
cout << "ArrayBase's Itr .vfunc(): " << itr.vfunc() <<std::endl;
cout << "EnhancedArray's Itr .vfunc(): " << eitr.vfunc() <<std::endl;
return 0;
}
Both calls to vfunc() above return 1, when I want the second call to return 0.
In main(), I know that if I change the ItrBase types to ItrBase &'s, I do get the desired return types, but then I am modifying my 'existing' code in hundreds of areas, and the destructors for the Iterators are not called.
Is there another strategy that I am not seeing?
Thanks.
Sure, if you're allowed to rewrite ItrBase, then you can use delegation to pass all function calls through to an implementation class, which you hold by pointer or reference so that polymorphism is in effect. This would look a lot like pimpl. And the callers would not have to be written at all, only recompiled.
EDIT: code for those not familiar with pimpl.
struct ItrBase
{
struct ItrImpl
{
virtual ~ItrImpl(){}
virtual int vfunc() = 0;
};
ItrBase(ItrImpl peer) : m_peer(peer) { cout << "ItrBase constructor.\n"; }
~ItrBase() { cout << "ItrBase destructor.\n"; }
int vfunc() { return m_peer->vfunc(); }
private:
const unique_ptr<ItrImpl> m_peer;
};
class ArrayBase
{
struct ItrImpl : public ItrBase::ItrImpl
{
virtual int vfunc() { return 0; }
};
public:
ArrayBase() { cout << "ArrayBase constructor.\n"; };
~ArrayBase() { cout << "ArrayBase destructor.\n"; };
virtual ItrBase createItr() { cout << "in AB's createItr()\n"; return ItrBase(new ItrImpl); };
};
class EnhancedArray : public ArrayBase
{
struct ItrImpl : public ItrBase::ItrImpl
{
virtual int vfunc() { return 1; }
};
public:
EnhancedArray() { cout << "EnhancedArray constructor.\n"; };
~EnhancedArray() { cout << "EnhancedArray destructor.\n"; };
virtual ItrBase createItr() { cout << "in EA's createItr()\n"; return ItrBase(new ItrImpl); };
};
You're running into a problem called slicing: createItr returns a reference, and then you're copying that into an ItrBase by-value. It's as if you did something like this:
EnhancedItr itr1 = ...;
BaseItr itr2 = itr1; // copy by-value
cout << itr2.vfunc(); // prints 1, not 0
You're also leaking memory: createItr returns a newly allocated object, but you're never deleting it. This is very bad, especially since you'd expect array iterators to be used frequently.
completely different thing you can do is use,
BOOST_AUTO(iterator, array);
and let compiler figure out return type.
BOOST_AUTO
Not being up-to-date with the Standard Library, I could not use the unique_ptr<> implementation suggested by Ben Voigt. (version >=4.3) I believe I have taken his concept and implemented it with basic pointers instead. Noting, however, that this implementation is not exception-safe. ItrImpl objects could be left undeleted.
Here's my code. Too bad createItr() has to return a ItrBase object rather than a pointer, otherwise I think I could have gotten auto_ptr<> to work. Output during program execution shows that ~ItrBase() is called only once for each instance, but I am suprised it is not called also during the object return from createItr(). Return value optimization?
#include <iostream>
using namespace std;
struct ItrBase
{
struct ItrImpl
{
virtual ~ItrImpl(){};
virtual int vfunc() const = 0;
};
ItrBase(ItrImpl* peer) : m_peer(peer) { cout << "ItrBase constructor.\n"; };
~ItrBase() { cout << "ItrBase destructor. \n"; delete m_peer; };
int getData() const { return m_peer->vfunc(); };
private:
ItrImpl* const m_peer;
};
class ArrayBase
{
struct ItrImpl : public ItrBase::ItrImpl
{
virtual int vfunc() const { return 0; };
};
public:
ArrayBase() { cout << "ArrayBase constructor.\n"; };
~ArrayBase() { cout << "ArrayBase destructor.\n"; };
virtual ItrBase createItr() { cout << "in AB's createItr()\n"; return ItrBase(new ItrImpl); };
};
class EnhancedArray : public ArrayBase
{
struct ItrImpl : public ItrBase::ItrImpl
{
virtual int vfunc() const { return 1; };
};
public:
EnhancedArray() { cout << "EnhancedArray constructor.\n"; };
~EnhancedArray() { cout << "EnhancedArray destructor.\n"; };
virtual ItrBase createItr() { cout << "in EA's createItr()\n"; return ItrBase(new ItrImpl); };
};
int main()
{
ArrayBase ab;
EnhancedArray ea;
ItrBase itr = ab.createItr();
ItrBase eitr = ea.createItr(); //EnhancedItr assigned to ItrBase
cout << "ArrayBase's Itr .vfunc(): " << itr.getData() <<std::endl;
cout << "EnhancedArray's Itr .vfunc(): " << eitr.getData() <<std::endl;
return 0;
}