几个c++向量问题

A few C++ vector questions

本文关键字:问题 向量 c++ 几个      更新时间:2023-10-16

我正在尝试学习一些c++,首先我创建了一些方法来处理控制台的输出和读取。我有两个主要问题,在代码中标记,在std::引用传递的字符串向量中操作/访问值。

下面的方法接受一个询问用户的问题(std string)和一个包含用户认为可接受的响应的vector std string。为了学习,我还想访问vector中的字符串并更改其值。

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(索引)来获取值,但我已经读到[]应该使用,但我不确定应该是什么样子(validInputs[I]不编译)。

4)我认为,由于深度复制是不必要的,它的良好做法是传递一个指针到上面的向量,有人可以验证吗?

5)我听说在循环中++ I比i++更好,这是真的吗?为什么?

3)在这种情况下,atoperator[]应该没有显著差异。注意,您使用的是指向向量的指针,而不是指向向量的指针(也不是指向向量的引用),因此必须使用(*validInputs)[i]validInputs->operator[](i)来使用操作符重载。如果您不想使用其他任何一种方法,则可以使用validInputs->at(i)。(at方法会在参数超出数组边界时抛出异常,而operator[]方法在参数超出数组边界时有未定义的行为。由于operator[]跳过边界检查,如果您知道事实 i在向量的边界内,则速度会更快。如果您不确定,请使用at并准备捕获异常。

4)指针很好,但引用会更好。如果不修改方法中的向量,最好使用对const-vector的引用(std::vector<std::string> const &)。这确保了不能向您传递空指针(引用不能为空),同时也确保您不会意外修改vector。

5)通常是这样。i++是后增量,即必须复制原值,然后对i进行自增,返回原值的副本。++ii加1,然后返回i,因此通常更快,特别是在处理复杂的迭代器时。对于unsigned int,编译器应该足够聪明地意识到预增量将是好的,但如果您不需要i的原始未增量值,则最好进入使用++i的实践。

我将使用对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;
        }
    }
}

如果你看不懂代码,请阅读有关迭代器的内容。当然,如果你需要,可以问其他问题。

我不打算解决第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 s,这几乎无关紧要,但对于潜在的胖迭代器,如果您不需要或不关心其返回值,则预增是更有效的选择。

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

3)先对指针解引用,然后对vector对象建立索引:
(*validInputs)[i]

4)引用被认为是更好的风格。尤其是那些永远不会为NULL的指针。

5)对于整数,这无关紧要(除非你计算表达式的结果)。对于其他对象,使用重载的++操作符(例如迭代器),最好使用++i。但在实践中,对于++操作符的内联定义,它可能会被优化为相同的代码。