首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++抽象类与继承

C++抽象类与继承
EN

Stack Overflow用户
提问于 2018-04-06 08:26:21
回答 3查看 87关注 0票数 2

我想解决这个问题。基本上,基类有一个函数映射,它以一个向量作为输入,并在执行了一些映射函数(这里是- f )之后输出最终的向量。然而,当我在主函数中打印出2*testVector-test1时,却得到了适当的输出,即6,-182等等,我真的不明白为什么.但是当我打印出2 *测试向量-测试2时,它仍然是相同的向量。

当我两次创建"DoubleElements“或两次调用同一个"DoubleElements”指针(它只执行1次映射)时,就会发生这种情况。我是不是从根本上缺少了一些理解?任何帮助都是非常感谢的!

代码语言:javascript
复制
#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;
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-04-06 08:32:23

代码语言:javascript
复制
static int iter = 0;

除非100%必要,否则应避免在方法中声明本地静态变量。

第一个调用会将iter增加到5,但是在下一个调用中,由于它是静态的,所以iter不会将它的值重置为0。

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

代码语言:javascript
复制
void test()
{
    static int x = 0;
    ++x;    
    cout << x << endl;
}

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

威尔输出

代码语言:javascript
复制
1
2
票数 2
EN

Stack Overflow用户

发布于 2018-04-06 08:44:55

来自class.static.data.static.data/1

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

对于iter来说,是static。它是class RecursiveBase 的一部分,而不是RecursiveBase对象的部分。

若要修复此问题,请将iter重置为0

代码语言:javascript
复制
if (iter == 5) {
   iter = 0; // reset iter
   return baseVector;
}

输出

代码语言:javascript
复制
2*testVector - test1
9
-273
-126
-48
39
2*testVector - test2
9
-273
-126
-48
39
票数 1
EN

Stack Overflow用户

发布于 2018-04-06 09:05:30

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

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

代码语言:javascript
复制
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);
}

但这仍然是对递归的无端使用。更好的解决办法是

代码语言:javascript
复制
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 *在你的主

代码语言:javascript
复制
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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49688497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档