zar
zar

Reputation: 12247

How to access aggregate in a derived class

I know some would say it is object slicing problem but I don't think it is. I have seen many related post on this site but not quite the same. Lets begin with code:

#include "stdafx.h"

#include <list>

struct MY_STRUCT
{
    int a;
    int b;
};

class File
{
public:

    virtual void Load(char * fileName) = 0;
};

class ExcelFile : public File
{
protected:
    std::list<MY_STRUCT> my_list;
public:

    ExcelFile(){};
    ~ExcelFile(){};

    virtual void Load(char * fileName)
    {
        // load the file into my_list
    }
};



int _tmain(int argc, _TCHAR* argv[])
{
    char fileName[] = "test.txt";

    File * file = new ExcelFile;

    file->Load( fileName );

    // Now I need to fill a Windows List or CListView from my_list data but how?
    // I can't access or iterate my_list here and I am not too sure if
    // should pass a windows object to the class to fill it up?
    // Even if I iterate by adding a member function to return the list object, wouldn't not
    // it violate the data encapsulation rule thereby defeating the purpose of having
    // interface class?

    return 0;
}

So basically I have an interface class whose derived class has the data in an aggregate (collection). Now I want to display the data. What is the right way to do that? I have mentioned the problem in comments in the code...I think I have found the answer while writing this post and I should let the class add function which fills the list. And I guess if I have to fill a ListBox or ListView than I would need to two functions one for each list. I am wondering if I can do better with visitor pattern!?

Upvotes: 0

Views: 502

Answers (2)

Tyler Jandreau
Tyler Jandreau

Reputation: 4335

There doesn't appear (if I understand your question correctly) to have any worry for object splicing. It looks like all you want to do is view the list from the "aggregate" class, in this case: ExcelFile()

Add a method to ExcelFile(), maybe something like print(), or if you want to get fancy:

std::ostream & operator<<(std::ostream &os) {
    std::list<MY_STRUCT>::iterator it;
    for (it = my_list.begin(); it != my_list.end(); ++it) {
        os << "A: " << it.a << ", B: " << it.b << std::endl;
    }

    return os;
}

Note: Code hasn't been compiled or run, it's just a guideline.

EDIT

If the OP wants to use his list elsewhere, return a constant reference to the set:

const std::list<MY_STRUCT> & getSet() const {
   return my_list;
}

Upvotes: 1

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

Simply provide at least a getter for your my_list member for safe access from outside the class (which wouldn't violate any encapsulation rules!):

class ExcelFile
{
public:
    // ...
    const std::list<MY_STRUCT>& getMyList() const { return my_list; }
    // ...
}

Upvotes: 0

Related Questions