I've been trying to write a program in C++11 for some artificial intelligence that returns a vector of objects. In order to ensure that the objects don't get deleted after the function exits, I've made them static as well as the vector. Here's the method (the other methods in the class don't matter for this, as well as the inner workings of the objects I'm placing in my vector - all that's relevant is the name of the class, H
), as well as the testing function:
//hvote.h
#ifndef __HVOTE_H_INCLUDED__
#define __HVOTE_H_INCLUDED__
#include <iostream>
#include <algorithm>
#include <vector>
#include <math.h>
#include "h.h"
class Hvote
{
public:
Hvote();
//This method is the class's constructor.
//It sets both hs and alphas to empty vectors.
//There are a bunch of instance variables and methods not shown here.
std::vector<H>& find_hs(std::vector<std::vector<double>>&, std::vector<bool>&);
//This method finds and returns the heuristics needed for the boosting algorithm.
};
#endif
//hvote.cpp
Hvote::Hvote()
{
//some code to initialize the instance variables.
}
//some other methods.
std::vector<H>& Hvote::find_hs(std::vector<std::vector<double>>& points,
std::vector<bool>& answers)
{
static std::vector<H> available_hs;
int axes = points[0].size();
for (int axis = 0; axis < axes; axis = axis + 1)
{
std::sort(points.begin(),
points.end(),
[=](std::vector<double> a, std::vector<double> b) mutable -> bool
{
return (a[axis] < b[axis]);
}
);
double previous = points[0][axis];
for (int datapoint = 0; datapoint < points.size() - 1; datapoint = datapoint + 1)
{
double next = points[datapoint + 1][axis];
if (next != previous)
{
if (answers[datapoint + 1] != answers[datapoint])
{
static H next_positive(axis, (next + previous)/2, true);
static H next_negative(axis, (next + previous)/2, false);
available_hs.push_back(next_positive);
available_hs.push_back(next_negative);
}
}
previous = next;
}
}
static std::vector<H>& available_hs_ref = available_hs;
return available_hs_ref;
}
//main.cpp
#include <iostream>
#include <vector>
#include "h.h"
#include "hvote.h"
int main()
{
Hvote hvote;
std::vector<std::vector<double>> points;
std::vector<bool> answers;
for (double x = 1.0; x < 21.0; x = x + 1.0)
{
for (double y = 1.0; y < 21.0; y = y + 1.0)
{
std::vector<double> point{x, y};
points.push_back(point);
bool answer = (x < y);
answers.push_back(answer);
}
}
std::vector<std::vector<double>>& points_ref = points;
std::vector<bool>& answers_ref = answers;
std::vector<H>& hs = hvote.find_hs(points_ref, answers_ref);
for (int i = 0; i < hs.size(); i = i + 1)
{
int axis = hs[i].get_axis();
double cutoff = hs[i].get_cutoff();
bool direction = hs[i].get_direction();
std::cout << "Heuristic(axis = " << axis << ", cutoff = " << cutoff << ", direction = " << direction << ")" << std::endl;
}
return 0;
}
I was expecting a variety of H
objects to appear on the output, with different axes, cutoffs, and directions, but to my surprise only two distinct instances of the H
class (and a lot of duplicates of those two) appear in hs
! Here's the output:
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
Heuristic(axis = 0, cutoff = 1.5, direction = 1)
Heuristic(axis = 0, cutoff = 1.5, direction = 0)
I checked that axis
, next
, previous
, etc. variables do change throughout the course of the program by printing their values. I finally came to the conclusion that next_positive
and next_negative
just aren't changing. Why? Why do these variables refuse to change? So far as I understand (second answer), making a variable static
just tells the compiler to leave it alone for the duration of its use (don't delete it after the method exits if it was returned and other methods will need to use it). Does static
somehow imply const
? What's the deal here?
Thanks!