Click here to Skip to main content
15,885,366 members
Articles / Programming Languages / C++
Tip/Trick

Collect data from an object of some other class

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
28 Feb 2010CPOL1 min read 7.6K   2  
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...
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;
// update a 
// ...
B b = a; // get a data to b


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; // the compiler will use b(a) to achieve it

    std::wcout << b.i << L'\t' << b.s << std::endl; // visualize the result

    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; // same as earlier

    AA<8> aa = a; // a AA having the values of previous A plus an array of eight int
    BB bb = aa; // Collect the aa data into bb

    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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
France France
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --