【问题标题】:accessing instance variable from another template class从另一个模板类访问实例变量
【发布时间】:2013-10-28 11:46:26
【问题描述】:

(大多是从accessing variable from another class template粘贴来分隔两个问题)

我正在尝试创建一个容器类系统,可以与数据加载器类一起使用以从文本文件中加载数据

这里有两类数据:

class Customer
{
    //...
};

class Tour
{
    std::vector<Customer*> custPtrs;
    //...
};

这是我的两个容器类:

template <class T>
class P_VContainer
{
    boost::ptr_vector<T> data;
    //...
};

template <class T>
class ListContainer
{
    std::list<T> data;
    //...
};

最后是我的数据加载器模板:

template<template<class> class T>
class DataLoader
{
    T<Customer> custList;
    T<Tour> tourList;

    //...
};

我在 Customer 和 Tour 中重载了 >> 运算符,以便可以将 ifstream 传递给它们,从流中取出一行,标记化并将其放入对象实例变量中。

容器类按顺序处理插入,数据加载器管理列表并创建 ifstream,以便将其传递给对象。

这是我的问题:

我首先加载我的客户文件,然后填充该列表。

之后,我必须加载旅行,其中包含预订客户的 customerID,并且我想将这些客户存储在每个旅行对象中的指针向量中,以便轻松访问客户信息。

目前我将 customerIDs 存储为字符串列表,然后当所有旅行都加载完毕后,将 custList 传递给通过 custList 搜索的函数,将其与字符串列表匹配

这意味着我必须维护两个列表,一个是字符串,另一个是指针,并且基本上是双重处理所有数据。考虑到数据集非常大,这意味着加载时间要长得多。

所以我想知道是否有一种方法可以从 Tour 的重载 >> 运算符内部访问 custList 实例变量,并在创建 Tour 对象时生成指针列表?

从技术上讲,一切都发生在 DataLoader 类的范围内,所以我认为这应该是可能的,但我只是不太确定如何去做.. 也许让它成为一个朋友类?我试过这样做,但到目前为止还没有运气..

任何帮助将不胜感激,对于冗长的解释感到抱歉,希望它有意义..

【问题讨论】:

  • 客户与旅游的关系如何?了解这两种数据类型之间的关系很重要。从逻辑上讲,我假设客户类型拥有旅游列表。
  • 既不从彼此继承,反之亦然,Tour 拥有一个客户列表,这就是为什么我需要在创建 Tour 对象时访问已加载的客户列表.. 我会更新反映关系的代码..
  • "目前我将 customerIDs 存储为字符串列表,然后当所有旅行都加载完毕后,将 custList 传递给通过 custList 搜索的函数,将其与字符串列表匹配"我认为boost::serialize 可以在内部处理这种情况。无论如何,当客户 ID 列表也应该工作时,为什么需要 Tour 中的指针列表?如果您确实需要指针,您可以通过&gt;&gt; 的左侧提供客户列表,即mysource &gt;&gt; someTour,并为mysource 使用自定义类型。

标签: c++ instance-variables friend-function


【解决方案1】:

最终的流使用可能如下所示:

custStream >> customers >> toursStream >> tours;

要实现这一点,您必须用两个流包装 ifstream - 用于客户和旅游,并将客户列表保留在流中,这是代码,您可以将容器替换为您喜欢的:

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

class CustomersInFileStream {
public:
    std::vector<Customer> customers;
    std::ifstream &input;
    CustomersInFileStream(std::ifstream &fileIn)
        :input(fileIn){
    }
};

class ToursInFileStream {
public:
    std::vector<Customer> customers;
    std::ifstream &input;
    ToursInFileStream(std::ifstream &fileIn)
        :input(fileIn){
    }
};

CustomersInFileStream &operator>>(CustomersInFileStream &input, std::vector<Customer> customers) {
    // perform file parsing here using ifstream member
    input.customers = customers;
    return input;
}

ToursInFileStream &operator>>(CustomersInFileStream &customersStream,
                                  ToursInFileStream &toursStream) {
    toursStream.customers = customersStream.customers;
    return toursStream;
}

ToursInFileStream &operator>>(ToursInFileStream &input, std::vector<Tour> tours) {
    // perform file parsing here using ifstream member
    // you also do have customers list here
    return input;
}

int main()
{

    std::ifstream customersFile("~/customers.txt");
    std::ifstream toursFile("~/tours.txt");

    CustomersInFileStream custStream(customersFile);
    ToursInFileStream toursStream(toursFile);

    std::vector<Customer> customers;
    std::vector<Tour> tours;

    custStream >> customers >> toursStream >> tours;

    return 0;
}

【讨论】:

  • 我宁愿建议使用客户列表作为 ctor 的参数创建自定义流,而不是使用 operator&gt;&gt;,因为它不是流提取;但除此之外,+1,我还想在我对 OP 的评论中提出某种形式的建议。
  • @DyP custStream >> customers 返回作为 >> tours 的输入参数的 CustomersInFileStream。测试也很顺利,你预计它会在哪里失败?
  • 所有运营商都在那里,但使用错过了旅游流,现在已修复。
  • 好吧,这就是我所说的“转换”。隐含的custStream &gt;&gt; toursStream 复制数据(顺便说一句,这是不必要的),所以我不会像流提取那样写它。我想到了ToursInFileStream toursStream(toursFile, customers); toursStream &gt;&gt; tours; 之类的东西,toursStream 存储了对客户列表的引用。
猜你喜欢
  • 2012-05-21
  • 1970-01-01
  • 1970-01-01
  • 2020-04-14
  • 2011-04-28
  • 2012-01-23
  • 2011-07-26
  • 1970-01-01
相关资源
最近更新 更多