There are circumstances, such as report or log entry, where we need to collect data from an object of some other (related or not) class.
The C++ language only requires that we
instruct the compiler how we intend to do it.
This is simply achieved by defining a constructor of
recipient_class
from
const source_class&
. We can then use the
operator =()
(or the constructor) to copy the relevant data into an object that we can print, save or whatever.
class A
{
};
class B
{
B(const A& a)
{
}
};
A a;
B b = a;
Actually we can even change the data type in this process: this minimal console application gets a
double
from a
A
and sets it's string representation in a
B
.
Paste it into a VC console application project, compile and run.
#include <iostream>
#include <sstream>
struct A
{
int i;
double d;
};
struct B
{
B(const A& a) : i(a.i)
{
std::wostringstream oss;
oss << a.d;
s = oss.str();
}
int i;
std::wstring s;
};
int main(int, wchar_t*)
{
A a = {100, 1.2345};
B b = a;
std::wcout << b.i << L'\t' << b.s << std::endl;
return 0;
}
With the power of C++ (and the help of some analysis) we should not have to write
several thousands such constructors. For instance, change the B constructor to:
template <class T>
B(const T& t) : i(t.i)
{
std::wostringstream oss;
oss << t.d;
s = oss.str();
}
Now
B::operator =()
operates on objects of any class presenting a
i
named member convertible to a
int
and a
d
named member accepted by
std::basic_ostream::operator <<()
.
With the added power of the Standard C++ Library (and again the help of some analysis) we can also handle all types and sizes of (for instance) int collections:
#include <vector>
struct BB : B
{
template<class T>
BB(const T& t) : BB::B(t), ai(t.ai.begin(), t.ai.end())
{}
std::vector<int> ai;
};
A
BB
is a
B
with an added
std::vector<int> ai
member.
It is constructible from any class presenting the previous traits and a member
standard container of objects convertible to int named
ai
, for instance from:
#include <array>
template <size_t t_s>
struct AA : A
{
std::array<int, t_s> ai;
AA(const A& a) : A(a)
{
for (int i = 0; i < t_s; ++i)
ai[i] = i;
}
};
The main() demo becomes then:
int main(int, wchar_t*)
{
A a = {100, 1.2345};
B b = a;
std::wcout << b.i << L'\t' << b.s << std::endl;
AA<8> aa = a;
BB bb = aa;
std::wcout << bb.i << L'\t' << bb.s;
for (size_t i = 0; i < bb.ai.size(); ++i)
std::wcout << L'\t' << bb.ai[i];
std::wcout << std::endl;
return 0;
}
Definitely no need of the complex constructs that you can find elsewhere (including CodeProject) :)
cheers,
AR