Child virtual method isn't called !

COMPONENT.HPP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#ifndef KENG_OBJ_TYPES_COMPONENT_HPP_INCLUDED
#define KENG_OBJ_TYPES_COMPONENT_HPP_INCLUDED

#include <list>
#include "../main/obj_type_id.hh"

#define TCOMPONENT UNIQUE_OBJ_TYPE_ID

namespace Keng {

//~~~~~~~~~~~~~~~~~
/// Iterator
//~~~~~~~~~~~~~~~~~
class TComponent;
class TComponent_iterator {
    friend class TBasis;

    private:
        std::list<TComponent>::iterator iterator;
};
//~~~~~~~~~~~~~~~~~
/// Main
//~~~~~~~~~~~~~~~~~
class TBasis;
class TComponent :
    public TComponent_iterator
{
    public:
        unsigned const& typeId = _typeId;
        TBasis* const& base = _base;
        unsigned const& position = _position;

        TComponent(
            TBasis* base = 0,
            unsigned position = 0);

        virtual ~TComponent();

        virtual void update();
        virtual void remove();

    protected:
        TComponent(
            unsigned typeId,
            TBasis* base,
            unsigned position);

    private:
        unsigned _typeId;
        TBasis* _base;
        unsigned _position;
};

}

#endif // KENG_OBJ_TYPES_COMPONENT_HPP_INCLUDED 


BACKGROUND.HPP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#ifndef KENG_OBJ_TYPES_BACKGROUND_HPP_INCLUDED
#define KENG_OBJ_TYPES_BACKGROUND_HPP_INCLUDED

#include "basis.hpp"
#include "../main/obj_type_id.hh"

#define TBACKGROUND UNIQUE_OBJ_TYPE_ID

namespace Keng {

//~~~~~~~~~~~~~~~~~
/// Main
//~~~~~~~~~~~~~~~~~
class TBackground :
    public TComponent
{
    public:
        TBackground(
            TBasis* base = 0,
            unsigned position = 0);

        virtual void update(); //VIRTUAL

        void kappa(); //NOT VIRTUAL

    protected:
        TBackground(
            unsigned typeId,
            TBasis* base,
            unsigned position);
};

}

#endif // KENG_OBJ_TYPES_BACKGROUND_HPP_INCLUDED 


Below is the code where I call update method.
1 single component existing there in the list is of TBackground class.

1
2
3
4
5
6
7
8
    for (TComponent& component : component_list) {
        component.update(); //doesn't call child virtual, but parent instead

        TBackground background = static_cast<TBackground&>(component);

        background.update(); //doesn't call child virtual, but parent instead
        background.kappa(); //calls child not virtual
    }


WHY? :[

Edit:
Is it because TComponent_iterator doesn't have update method?

Edit:
Nope, as I add it, and it changes nothing.

Edit:
Well, I re-compile and launch from time to time, changing things a bit and then back, and it works differently. Once child is called, once parent.

Edit:
dynamic_cast crashes.

Edit:
This all seems like it doesn't create TBackground object, but TComponent. But I certainly do TComponent creation. What's wrong with TBackground?
Last edited on
What is the type of component_list?
Note that a std::list<TComponent> can only store objects of type TComponent. It can not store objects of any other class. If you try to insert a TBackground object into such a list the object would be converted to a TComponent and stored in the list (see object slicing: https://en.wikipedia.org/wiki/Object_slicing)

If you want to store objects that are instances of subclasses of TComponent you have to store pointers (or smart pointers) in the list.
Last edited on
Wow, thanks!
I stored objects but not pointers to utilize clear method, but how would that do that if it's of 1 type indeed.
So I have to go through container and delete by myself. :[
Last edited on
So I have to go through container and delete by myself. :[

Not if you use smart pointers like std::unique_ptr or std::shared_ptr.
dynamic_cast crashes.

How did you do it?

The result of static_cast is undefined behaviour.

The dynamic_cast returns 0, if the cast is not possible. One should test for it:
1
2
3
4
5
6
7
Derived bar;
Base * foo = &bar;

if ( auto gaz = dynamic_cast<Derived*>(foo) ) {
  // use gaz
}
// else foo is not a pointer to Derived object 
keskiverto, if you check like that, ofc. I didn't know how to do that and just called child method. Ofc it crashed as TBackground was converted into TComponent when put to list.

unique_ptr, that's what I currently need.

Ty all.
Topic archived. No new replies allowed.