0

我知道有些人会说这是对象切片问题,但我不这么认为。我在这个网站上看到了很多相关的帖子,但并不完全相同。让我们从代码开始:

#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;
}

所以基本上我有一个接口类,其派生类具有聚合(集合)中的数据。现在我想显示数据。这样做的正确方法是什么?我在代码的注释中提到了这个问题......我想我在写这篇文章时已经找到了答案,我应该让类添加填充列表的函数。而且我想如果我必须填写一个 ListBox 或 ListView 比我需要两个函数一个列表。我想知道我是否可以用访客模式做得更好!?

4

2 回答 2

1

似乎没有(如果我正确理解您的问题)担心对象拼接。看起来您想要做的就是查看“聚合”类中的列表,在这种情况下:ExcelFile()

向 中添加一个方法ExcelFile(),可能类似于print(),或者如果您想花哨的话:

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;
}

注意:代码尚未编译或运行,它只是一个指南。

编辑

如果 OP 想在其他地方使用他的列表,请返回对集合的常量引用:

const std::list<MY_STRUCT> & getSet() const {
   return my_list;
}
于 2013-10-28T21:53:44.703 回答
0

只需为您的成员提供至少一个 getter,以便my_list从类外部安全访问(这不会违反任何封装规则!):

class ExcelFile
{
public:
    // ...
    const std::list<MY_STRUCT>& getMyList() const { return my_list; }
    // ...
}
于 2013-10-28T21:53:29.807 回答