【问题标题】:C++ "=" operator behavior for a class with a private vector and iterator for it具有私有向量和迭代器的类的 C++“=”运算符行为
【发布时间】:2016-11-30 08:26:52
【问题描述】:

我正在尝试创建一个按顺序提供输出的对象,但我不想公开内部实现。我希望其他类只看到方法 hasNextOutput() 和 nextOutput()。这里分别是我的头文件和类文件:

头文件:

#ifndef RADAR_OUTPUT_GENERATOR_H
#define RADAR_OUTPUT_GENERATOR_H

#include<vector>
#include<iterator>
#include "asl/include/net/asl_net_user_data.h"

class RadarOutputGenerator {
private:
    int dataCounter;    
    std::vector<unsigned char *> dataStream;
    std::vector<unsigned char *>::iterator dataStreamIterator;
public:
    RadarOutputGenerator();
    RadarOutputGenerator(char *filename);
    RadarOutputGenerator(unsigned int maxDataSize);
    ~RadarOutputGenerator();

    bool hasNextOutput();
    void nextOutput(unsigned char *&dataWithHeader);
};

#endif

类实现

#include "radar_output_generator.h";

RadarOutputGenerator::RadarOutputGenerator() {

}

RadarOutputGenerator::RadarOutputGenerator(unsigned int maxDataSize) {
    for (int i = 0; i < 100; i++) {
        // create some data

        this->dataStream.push_back(data);

        cur_step = (cur_step += 10) & 65535;
    }

    this->dataStreamIterator = (this->dataStream).begin();
}

bool RadarOutputGenerator::hasNextOutput() {
    return (this->dataStreamIterator != this->dataStream.end());
}

void RadarOutputGenerator::nextOutput(unsigned char *&dataWithHeader) {
    dataWithHeader = *(this->dataStreamIterator++);
}

问题是,当我构造一个类型为 RadarOutputGenerator 的对象时,hasNext() 方法因“迭代器不兼容”错误而失败,例如此代码失败:

RadarOutputGenerator myOutputGenerator = RadarOutputGenerator(47);
radarOutputGenerator.hasNextOutput(); // this line fails

我想我知道问题出在哪里了——可能在调用“=”运算符时,向量 dataStream 被复制并且在构造函数中初始化的迭代器保持对原始向量的引用。如果是这样的话,这种行为让我很失望,但我想知道如何正确解决这个问题。

【问题讨论】:

  • 您知道,当您像这样定义和初始化一个对象时,您不会调用赋值运算符,而是调用 复制构造函数。你通过实现一个复制构造函数一个赋值运算符来“解决”这个问题(请阅读rules of three, five and zero)。
  • 您需要重载复制赋值运算符和复制构造函数(以及移动分配和移动复制),或者放弃迭代器并改用索引。
  • 另一种可能性是对向量使用 shared_ptr,这样所有相互复制的生成器都使用相同的数据流。如果您需要在迭代过程中修改流,请将其设为写时复制。
  • 我不太明白您的要求是什么。您是否希望将流转换为数据包序列?
  • 我没有任何流,可能是已经包含单个数据包的文件,但我没有在问题中提及它,因为我认为它不相关。此类的主要目的只是按照特定硬件设备(雷达)的协议生成一系列有效数据包,我的第一种方法只是在构造函数中生成这些数据包并将它们存储在稍后将迭代的向量中以按顺序检索各个数据包。但是,如果您对如何改进代码有任何建议,我将不胜感激,即使这不是主要话题。

标签: c++ vector iterator operator-overloading


【解决方案1】:

解决这个问题的一种方法是重载复制构造函数和复制赋值运算符以做正确的事情,即计算迭代器在旧向量中的偏移量,并创建一个新的迭代器,将其指向新向量。

作为一般规则,只要一个对象有一个内部指针(指向它自己的一部分的东西),你就需要手动实现复制。

一个更简单但不是普遍适用的解决方案是像 n.m.在 cmets 中说并存储索引而不是迭代器。索引与特定向量无关。

【讨论】:

    猜你喜欢
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    • 2011-04-14
    相关资源
    最近更新 更多