2017-02-13 4 views
2

У меня есть вектор указателей функций, который по умолчанию инициализируется как член класса, поэтому он всегда имеет 2 элемента. Однако, читая его size(), я получаю тарабарщину. Я создал тривиальную, минимальную репликацию этой проблемы ниже.Вектор указателей fn не показывает правильный размер()

#include <iostream> 
#include <vector> 

using fnptr = float (*)(float); 

float fn1(float x){ return x;}; 
float fn2(float x){ return x;}; 

std::vector<fnptr> fnptrs(){ 
    std::vector<fnptr> ret; 
    ret.push_back(&fn1); 
    ret.push_back(&fn2); 
    return ret; 
} 

class Foo{ 
public: 

    int nFns()const{ 
    return fns.size(); 
    } 

private: 
    std::vector<fnptr> fns = fnptrs(); // always initialized 
}; 


class Baz { 
public: 
    explicit Baz(Foo f):foo{&f}{} 

    const Foo* foo; // my problem does not appear if this is not a pointer 

}; 

class Bar { 
public: 
    explicit Bar(Foo f):foo{f}{ 
    bazs.push_back(Baz(foo)); 
    bazs.push_back(Baz(foo)); 
    } 

    void viewSizes()const{ 
    for (auto& i:bazs) 
     std::cout << " i.foo->nFns() = " << i.foo->nFns() << "\n"; 
    } 

    const Foo foo; 
    std::vector<Baz> bazs; 

}; 

int main(int argc, const char * argv[]) { 

    Foo f; 
    Bar b(f); 

    b.viewSizes(); 

    return 0; 
} 

Выход:

i.foo->nFns() = -677271344 
i.foo->nFns() = -516 

Я не предпочитаю хранить Foo в Baz как указатель, но в моей реальной программе, у меня есть вектор Баз о том, что выгружена часто и ссылка не может для этого (не компилируется). Если я делаю его регулярным членом (не указателем или ссылкой), то у меня нет проблем, но с большим количеством этих объектов лучше не хранить одну и ту же копию в каждом объекте, поэтому мне нужно использовать указатель.

ответ

4

Здесь:

explicit Baz(Foo f):foo{&f}{} 

f является локальной переменной конструктора и испаряет после выхода из конструктора. Вероятно, вы захотите передать ссылку или фактический необработанный указатель.

+0

Спасибо, вы правы, но в моей нетривиальной программе я действительно использую ссылку, и я забыл сделать эту ссылку в этом тривиализованном примере. Это решает проблему для этого примера, поэтому мне нужно попытаться воссоздать проблему лучше как минимальный пример. – johnbakers

+0

Я считаю, что это привело меня в правильном направлении. Моя проблема была похожа на то, что вы описываете, спасибо. – johnbakers