1

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.

golobitch
  • 1,466
  • 3
  • 19
  • 38
  • 1
    1st of all wrong asking without giving a MCVE here! – πάντα ῥεῖ Jul 29 '15 at 20:23
  • Many things could be wrong in your code. How can any one help you without seeing your code? – R Sahu Jul 29 '15 at 20:23
  • 1
    I wonder if you have an object slicing problem... but without seeing code, who knows. – RyanP Jul 29 '15 at 20:24
  • I will provide source code then in next few minutes – golobitch Jul 29 '15 at 20:33
  • @RyanP Yes, sounds so thoroughly:http://stackoverflow.com/questions/274626/what-is-object-slicing – πάντα ῥεῖ Jul 29 '15 at 20:35
  • I've provided a source code. Unforunately I can't give you anything to compile because it would be too large :/ I can't break down this problem to few lines. Sorry. So, can any one of you see the problem? – golobitch Jul 29 '15 at 20:48
  • @RyanP and others, I read that question and answers about slicing problem and I understand what is the problem here. But also...I'm not sure about this. In `SortingTestSetIterator::get_current()`, I create instance of `SortingTestCase` and then I return pointer to this instance. I believe this is wrong?Because that instance is local variable? But if is not, would it be ok if I return pointer to this `SortingTestCase` instance, then in my main program I will saved it to `TestCase` and then I will send it to `SortingAbsAlgorithm::init(TestCase*)`, then, there I will cast it to `SortingTestCase`? – golobitch Jul 30 '15 at 18:13
  • Or am I imagine this all wrong? – golobitch Jul 30 '15 at 18:14
  • Ah, I figured it out. Actualy I wasn't doing nothing wrong (except that pointer). I just forget to initialize size of array to class member variable. Thank you for help – golobitch Jul 30 '15 at 18:38

0 Answers0