I have the following problem:
I have main executable program called algatorc. In this program, I have class called TestCase, AbsAlgorithm and TestSetIterator. End user must create new algatorc program and then inherits these three classes.
Let's say that end user creates project Sorting. He would end up with three classes called SortingTestCase, SortingTestSetIterator and SortingAbsAlgorithm.
So here is the thing. End user has a method SortingTestSetIterator::get_current and return type of this function is TestCase*. In this method, he creates instance of SortingTestCase and return this instance. So he actually returned child of TestCase. In my main program I save this pointer to TestCase *t (and no, I can't save it as SortingTestCase, because before runtime, I don't know the name of the project) and then I send this pointer to method SortingAbsAlgorithm::init(TestCase* test_case). In this particulary method, end user will probably cast this object to his (SortingTestCase), and this is done like this:
sorting_test_case = dynamic_cast<SortingTestCase*>(test);
This SortingTestCase is derived from TestCase and has all members from parent class and two variables of his own: array and size. So when in init method I say
for (int i = 0; i<sorting_test_case->size; i++)
{
std::cout << sorting_test_case[i] << std::endl;
}
then I get nothing. It seems like array is empty.
Any idea what am I doing wrong?
Edit:
class SortingAbsAlgorithm : public AbsAlgorithm
{
private:
SortingTestCase *sorting_test_case;
public:
bool init (TestCase *test)
{
sorting_test_case = dynamic_cast<SortingTestCase*>(test);
std::cout << "INIT ARRAY" << std::endl;
for (int i = 0; i<sorting_test_case->size; i++)
{
std::cout << sorting_test_case->array_to_sort[i] << " ";
}
}
};
class SortingTestCase : public TestCase
{
public:
int size;
int *array_to_sort;
void init_array(int tab[], int size)
{
array_to_sort = new int[size];
for (int i = 0; i<size; i++)
{
array_to_sort[i] = tab[i];
}
}
};
class SortingTestSetIterator : public TestSetIterator
{
private:
std::string file_path;
std::string test_file_name;
public:
TestCase *get_current()
{
if (current_input_line.empty())
{
return nullptr;
}
std::vector<std::string> fields;
std::string token;
std::stringstream str(current_input_line);
while ( getline(str, token, ':') )
{
fields.push_back(token);
}
str.clear();
if (fields.size() < 3)
{
report_invalid_data_format("to few fields");
return nullptr;
}
std::string test_name = fields.at(0);
int prob_size;
try
{
prob_size = std::atoi(fields.at(1).c_str());
} catch (...)
{
report_invalid_data_format("'n' is ot a number");
}
std::string group = fields.at(2);
std::string test_id = "Test-" + std::to_string(line_number);
EParameter *test_id_par = new EParameter("TestID", "Test identificator", test_id);
EParameter *parameter1 = new EParameter("Test", "Test name", test_name);
EParameter *parameter2 = new EParameter("N", "Number of elements", std::to_string(prob_size));
EParameter *parameter3 = new EParameter("Group", "A name of a group of tests", group);
SortingTestCase *t_case = new SortingTestCase();
t_case->addParameter(*test_id_par);
t_case->addParameter(*parameter1);
t_case->addParameter(*parameter2);
t_case->addParameter(*parameter3);
int arr[prob_size];
int i = 0;
if (group == "INLINE")
{
if (fields.size() < 4)
{
report_invalid_data_format("to few fields");
return nullptr;
}
std::vector<std::string> data;
std::stringstream ss(fields.at(3));
while (getline(ss, token, ' ') )
{
data.push_back(token);
}
if (data.size() != prob_size)
{
report_invalid_data_format("invalid number of inline data");
return nullptr;
}
try
{
for (i = 0; i<prob_size; i++)
{
arr[i] = std::atoi(data.at(i).c_str());
}
} catch (...)
{
report_invalid_data_format("invalid type of inline data - data " + std::to_string((i+1)));
return nullptr;
}
}
else if (group == "RND")
{
srand(time(NULL));
for (i = 0; i<prob_size; i++)
{
arr[i] = rand() % prob_size + 1000;
}
}
else if (group == "SORTED")
{
for (i = 0; i<prob_size; i++)
{
arr[i] = i;
}
}
else if (group == "INVERSED")
{
for (i = 0; i<prob_size; i++)
{
arr[i] = prob_size - i;
}
}
t_case->init_array(arr, prob_size);
return t_case;
}
};
This are end users classes. I create library out of this classes and I load them in my program via dlopen and dlsym. I get instance of classes like this:
#ifdef __cplusplus
extern "C" {
#endif
TestSetIterator * create_iterator_object() {
return new SortingTestSetIterator;
}
void destroy_iterator_object(TestSetIterator* object) {
delete object;
}
#ifdef __cplusplus
}
and then in my main program I load symbol create_iterator_object
create_it = (TestSetIterator* (*)())dlsym(handle, "create_iterator_object");
and then I say this:
TestSetIterator *it = (TestSetIterator*)create_it();
I can call it->get_current() which loads line from file to variable curent_input_line. So I do this:
TestCase *t_case = it->get_current();
and then I say
a->init(t_case)
a is here actually SortingAbsAlgorithm loaded exactly the same as TestSetIterator (ofcourse, different symbol) and is "saved" into AbsAlgorithm a*.
So when a->init(t_case) is called, then in this init end-user cast t_case this is type of TestCase to SortingTestCase. And when I want to print elements in array, array is empty.