简体   繁体   English

C ++抽象类和继承

[英]C++ Abstract Classes and Inheritance

I have this problem I'm trying to solve. 我有这个问题要解决。 Basically the base class has the function map, which takes a vector as input and outputs the final vector after some mapping function, in this case - f, has been performed. 基本上,基类具有函数映射,该函数映射将向量作为输入,并在执行某些映射功能(在这种情况下为f)之后输出最终向量。 However, I'm really lost as to why when I print out 2*testVector - test1 in the main function, I get proper output, ie 6, -182 etc... but when I print out 2*testVector - test 2, it's still the same vector. 但是,我真的迷失了为什么在主函数中打印出2 * testVector-test1时得到正确的输出,即6,-182等...但是当我打印出2 * testVector-test 2,它仍然是相同的向量。

This happens both when I create "DoubleElements" twice or just call the same "DoubleElements" pointer twice (it only ever performs 1 map). 当我两次创建“ DoubleElements”或只是两次调用同一“ DoubleElements”指针(仅执行一次映射)时,都会发生这种情况。 Am I fundamentally missing some understanding? 我从根本上缺乏了解吗? Any help is appreciated! 任何帮助表示赞赏!

#include <iostream>
#include <vector>
using namespace std;

class RecursiveBase {
public: 
vector<int> map(vector<int> baseVector) {
    static int iter = 0;
     // Base case, return the final vector. 
    if (iter == 5) {
        return baseVector;
    // Replace the element with the old element mapped to the function.
    } else {
        baseVector[iter] = this->f(baseVector[iter]);
        iter++;
        return map(baseVector);
    }
}

private:
    virtual int f(int value) = 0;
};

class DoubleElements: public RecursiveBase {
private:
    int f(int value) {
        return 3*value;
    }
};

int main() {
    vector<int> testVector, o1, o2;
    testVector.push_back(3);
    testVector.push_back(-91);
    testVector.push_back(-42);
    testVector.push_back(-16);
    testVector.push_back(13);

    DoubleElements de;
    DoubleElements de1;

    RecursiveBase *test1 = &de;
    RecursiveBase *test2 = &de1;

    o1 = test1->map(testVector);
    o2 = test2->map(testVector);

    std::cout << "2*testVector - test1" << std::endl;
    for (unsigned int iter = 0; iter < o1.size(); iter++) {
        std::cout << o1[iter] << std::endl;
    }

    std::cout << "2*testVector - test2" << std::endl;
    for (unsigned int iter = 0; iter < o2.size(); iter++) {
        std::cout << o2[iter] << std::endl;
    }
}
static int iter = 0;

You should avoid declaring local static variables in methods unless 100% necessary. 除非100%必要,否则应避免在方法中声明局部静态变量。

The first call will increment iter to 5, but on the next call, iter , since it's static, will not reset it's value to 0. 第一次调用将iter递增为5,但在下一次调用中,由于iter是静态的,因此不会将其值重置为0。

As an example, a simple program like: 例如,一个简单的程序如下:

void test()
{
    static int x = 0;
    ++x;    
    cout << x << endl;
}

int main()
{        
    test();
    test();    
    return 0;
}

Will output 将输出

1
2

From class.static.data/1 : class.static.data/1

A static data member is not part of the subobjects of a class. 静态数据成员不属于类的子对象。

For iter is static . 因为iterstatic It is part of the class RecursiveBase NOT part of the RecursiveBase objects. 它是class RecursiveBase一部分,而不是 RecursiveBase对象的一部分。

To fix it, reset iter to 0 : 要修复它,请将iter重置为0

if (iter == 5) {
   iter = 0; // reset iter
   return baseVector;
}

OUTPUT OUTPUT

2*testVector - test1
9
-273
-126
-48
39
2*testVector - test2
9
-273
-126
-48
39

You can only ever call RecursiveBase::map once as it stands, because the iter is static. 你永远只能调用RecursiveBase::map 曾经的样子,因为iter是静态的。 You also assume that you will only ever call it with a 5 element std::vector<int> , at which point std::array<int, 5> is a better choice. 您还假设只能使用5个元素std::vector<int>调用,此时std::array<int, 5>是一个更好的选择。

If you want a recursive solution, instead pass the index as an additional parameter 如果您需要递归解决方案,则将索引作为附加参数传递

public:
std::vector<int> map(std::vector<int> vec) {
    return do_map(vec, 0);
}
private:
std::vector<int> do_map(std::vector<int> & vec, std::size_t index) {
    if (index == vec.size()) { return vec; }
    vec[index] = f(vec[index]);
    return do_map(vec, ++index);
}

But that's still a gratuitous use of recursion. 但这仍然是递归的免费使用。 A much better solution is 更好的解决方案是

public:
std::vector<int> map(std::vector<int> vec) {
    std::transform(vec.begin(), vec.end(), vec.begin(), [this](int i) { return f(i); });
    return vec;
}

You also have superfluous RecursiveBase * in your main 您的主目录中也有多余的RecursiveBase *

int main() {
    std::vector<int> testVector{3, -91, -42, -16, 13};

    DoubleElements de;
    DoubleElements de1;

  // declare at point of initialisation
  // don't need ->
    auto o1 = de.map(testVector);
    auto o2 = de1.map(testVector);

    std::cout << "2*testVector - test1" << std::endl;
    for (unsigned int iter = 0; iter < o1.size(); iter++) {
        std::cout << o1[iter] << std::endl;
    }

    std::cout << "2*testVector - test2" << std::endl;
    for (unsigned int iter = 0; iter < o2.size(); iter++) {
        std::cout << o2[iter] << std::endl;
    }

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM