在方法中更改类的私有值而不将更改返回到main()

时间:2016-12-13 14:47:12

标签: c++ c++11

我遇到一个问题,我现在一周内没有找到答案。我有一个动态数组类,它有一个方法来向它添加字符串值。它应该代表您可以添加项目的库存。但是,我发现当我尝试在main()中稍后为类元素“backpack”调用print方法时,方法中对类元素的私有值所做的更改不会“更新”。我认为这可能是一个问题,因为引用问题,但是当一个类没有在一个不同的模块中时,我已经看到了这个工作。

我的“背包”模块打印并添加方法:

 const int INITIAL_SIZE = 5;
 Inventory::Inventory():
        array_(new string[INITIAL_SIZE]),
        max_space_(INITIAL_SIZE),
        used_space_(0) {}

 void Inventory::add(string item){

if ( size() == max_space_ ) {
    string* new_array = new string[2 * max_space_];

    for ( int i = 0; i < size(); ++i ) {
        new_array[i] = array_[i];
    }

    delete [] array_;

    array_ = new_array;
    max_space_ = 2 * max_space_;
}

array_[used_space_] = item;
++used_space_;
}

void Inventory::print() {

for ( int i = 0; i < size(); ++i ) {
    cout << array_[i] << endl;
}
}

main():

Inventory inv;
string input;

while (cout << "input> "
        and getline(cin,input)){

add_to_bag(input,inv);

所以关键是你在给它新内容时重置了库存。函数add_to_bag();是:

  void add_to_bag(string input, Inventory inv){

  const string WHITESPACE1_REGEX = "[[:space:]]*";
  const string WHITESPACE2_REGEX  = "[[:space:]]+";
  const string WORD_REGEX                      = "[[:alpha:]_]+";

  const string LINE_REGEX =
      WHITESPACE1_REGEX +
      WORD_REGEX +
      "(" +
      WHITESPACE2_REGEX +
       WORD_REGEX +
      ")*" +
      WHITESPACE1_REGEX;

regex line_reg(LINE_REGEX);
regex word_regex(WORD_REGEX);

string line = input;

    if ( regex_match(line, line_reg) ) {

        sregex_iterator iter(line.begin(), line.end(), word_regex);
        sregex_iterator end;

        while ( iter != end ) {
            inv.add(iter->str());
            ++iter;
        }

    } else {

        cout << "Error: unknown inventory contents." << endl;
    }
}

2 个答案:

答案 0 :(得分:6)

你的问题是:

    void add_to_bag(string input, Inventory inv);

您将Inventory对象的副本传递给add_to_bag。你修改那个副本......然后它被扔掉了。修复方法是通过引用传递:

    void add_to_bag(string input, Inventory &inv);

顺便说一下,在现实代码中,我强烈建议使用std::vector<std::string>而不是“自己动手”。这里有一些棘手的异常处理问题 - 除非Inventory没有析构函数(意味着内存泄漏),或者确实有一个正确的复制构造函数,我本来希望你遇到“双重免费”问题。 (阅读“三规则”。)

答案 1 :(得分:0)

设计课程的简单方法如下:

class Inventory {
private:
    std::vector<std::string> items_;

public:
    Inventory(){}
    ~Inventory(){}

    void addItem( const std::string& item ) {
       items_.push_back( item );
    }

    void printInventory() const {
        int idx = 0;
        for (; idx < items_.size(); ++idx ) {
            std::cout << items_[idx] << std::endl;
        }     
    }

    void clearInventory() {
        items_.clear();
    }
};

至于你的问题,Martin Bonner已经通过修改副本以及之后删除它以及内存管理的其他问题来回答它。