C++抽象类和继承

C++ Abstract Classes and Inheritance

本文关键字:继承 抽象类 C++      更新时间:2023-10-16

我有这个问题,我正在尝试解决。基本上基类具有函数映射,它以向量作为输入,并在执行某些映射函数(在本例中为 - f(后输出最终向量。但是,我真的很迷茫,为什么当我在主函数中打印出 2*testVector - test1 时,我得到了正确的输出,即 6、-182 等......但是当我打印出 2*testVector - test 2 时,它仍然是相同的向量。

当我创建两次"DoubleElements"或只是两次调用同一个"DoubleElements"指针(它只执行 1 个映射(时,都会发生这种情况。我从根本上错过了一些理解吗?任何帮助不胜感激!

#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;

应避免在方法中声明局部静态变量,除非 100% 必要。

第一次调用将iter增加到 5,但在下一次调用中,iter ,因为它是静态的,不会将其值重置为 0。

例如,一个简单的程序,如:

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

将输出

1
2

来自 class.static.data/1:

静态数据成员不是类的子对象的一部分。

因为iterstatic.它是class RecursiveBase的一部分,而不是RecursiveBase对象的一部分。

要修复它,请将iter重置为 0

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

输出

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

您只能按原样调用RecursiveBase::map一次,因为iter是静态的。你还假设你只会用 5 元素std::vector<int>来调用它,此时std::array<int, 5>是一个更好的选择。

如果需要递归解决方案,请将索引作为附加参数传递

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);
}

但这仍然是对递归的无端使用。一个更好的解决方案是

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;
}

你的主要内容中也有多余的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;
}