一些C ++向量问题

时间:2013-01-18 19:49:08

标签: c++ string pointers vector

我正在尝试学习一些c ++,开始时我创建了一些方法来处理输出和从控制台读取。 我有2个主要问题,在代码中标记,操纵/访问通过引用传入的字符串的std :: vector中的值。

下面的方法接受一个问题(std字符串)来询问用户以及包含来自用户的响应的向量std字符串被认为是可接受的。为了学习,我还想要访问向量中的字符串并更改其值。

std::string My_Namespace::My_Class::ask(std::string question, std::vector<std::string> *validInputs){
    bool val = false;
    std::string response;
    while(!val){
        //Ask and get a response
        response = ask(question);
        //Iterate through the acceptable responses looking for a match
        for(unsigned int i = 0; i < validInputs->size(); i++){
            if(response == validInputs->at(i)){
                ////1) Above condition always returns true/////
                val = true;
                break;
            }
        }
    }
//////////2) does not print anything//////////
println(validInputs->at(0)); //note the println method is just cout << param << "\n" << std::endl
//Really I want to manipulate its value (not the pointer the actual value)
//So I'd want something analogous to validInputs.set(index, newVal); from java
///////////////////////////////////////////
}

还有一些问题:

3)我在向量上使用.at(index)来获取值但是我已经读过应该使用[],但是我不确定它应该是什么样的(validInputs [i ]不编译)。

4)我认为,由于深度复制是不必要的,如上所述传递指向向量的指针,有人可以验证吗?

5)我听说++ i比循环中的i ++更好的练习,是真的吗?为什么呢?

4 个答案:

答案 0 :(得分:2)

3)在这种情况下使用atoperator[]应该没有显着差异。请注意,您有一个指向矢量的指针,而不是矢量(也不是矢量引用),因此您必须使用(*validInputs)[i]validInputs->operator[](i)来使用运算符重载。如果您不想使用这些其他方法,可以使用validInputs->at(i)。 (如果参数超出数组边界,at方法将抛出异常,而当参数超出数组边界时,operator[]方法具有未定义的行为。由于operator[]跳过边界检查,如果你知道事件 i在向量的范围内,它会更快。如果你不确定,请使用at并准备好抓住异常。)

4)指针很好,但参考会更好。如果你没有在方法中修改向量,那么引用到const-vector将是最好的(std::vector<std::string> const &)。这可以确保您不能传递空指针(引用不能为null),同时还要确保您不会意外地修改向量。

5)通常是。 i++是后递增的,这意味着必须复制原始值,然后递增i并返回原始值的副本。 ++i递增i然后返回i,因此它通常更快,特别是在处理复杂的迭代器时。使用unsigned int,编译器应该足够聪明,以便意识到预增量会很好,但如果您不需要原始的未增加的值,那么进入使用++i的做法是很好的。 i

答案 1 :(得分:2)

我使用引用到const和std::find。请注意,我也通过引用获取字符串(否则会深入复制):

std::string My_Class::
ask (const std::string& question, const std::vector<std::string>& validInputs)
{
    for (;;) {
        auto response = ask (question);
        auto i = std::find (validInputs.begin (), validInputs.end (), response);

        if (i != validInputs.end ()) {
             std::cout << *i << '\n'; // Prints the value found
             return *i;
        }
    }
}

如果您不理解代码,请阅读迭代器。当然,如果需要,可以随意提出其他问题。

答案 2 :(得分:1)

我不打算解决第1点和第2点,因为我们不知道你在做什么,我们甚至看不到askprintln的代码。

  

我在向量上使用.at(index)来获取值但我已经读过应该使用[],但是我不确定它应该是什么样的(validInputs [i]不会“编译”。

下标访问和at成员函数是不同的东西。它们给你完全相同的东西,一个对索引元素的引用,但是如果你传递一个越界索引,它们的行为会有所不同:at将抛出异常而[]将调用未定义的行为(如内置数组做)。在指针上使用[]有点难看,(*validInputs)[i],但是你应该尽可能避免使用指针。

  

我认为,由于深度复制是不必要的,如上所述传递指向向量的指针,有人可以验证吗?

不需要深层复制,但指针也是如此。你需要一个引用,并且需要一个const,因为我认为你不应该修改它们:

ask(std::string const& question, std::vector<std::string> const& validInputs)
  

我听说++ i比循环中的i ++更好的练习,是真的吗?为什么呢?

在一般情况下是正确的。这两个操作不同,++i递增i并返回新值,而i++递增i但返回递增前的值,这需要临时保持并且回。对于int来说,这几乎不重要,但对于潜在的脂肪迭代器,如果你不需要或不关心它的返回值,那么预增量会更有效率,也是更好的选择。

答案 3 :(得分:0)

要回答问题1和2,我们可能需要更多信息,例如:您是如何初始化validInputs的?问的来源是什么?

3)首先取消引用指针,然后索引向量:

(*validInputs)[i]

4)参考被认为是更好的风格。特别是代替从不为NULL的指针。

5)对于整数,它无关紧要(除非你评估表达式的结果)。对于其他对象,使用重载的++运算符(例如迭代器),使用++ i可能更好。但实际上,对于++运算符的内联定义,它可能会针对相同的代码进行优化。