Inheritance using Base Method with other name?

Hey guys,

I have 2 classes with a Function with the same definition (both inherited from the same base class) and in my derived class I derive from both of those 2. Is it possible to use the Methods of both classes? for example with an other name?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

class A
{
protected:
    int print(int a) { std::cout << "int A: " << a << std::endl; }
};
class B : A
{
protected:
    int print(int a) { std::cout << "int B: " << a << std::endl; }
};

class C : A
{
protected:
    int print(int a) { std::cout << "int C: " << a << std::endl; }
};
class D : B, C
{
public:
    using C::print;
    using B::print;
}:

is there something like using C::print as printc;?

The Problem, I have a Sprite class that derives from a Rectangle with properties Position, Size, Origin and Angle and a Text class that derives from Rectangle.
Now i have a Button class deriving from both Sprite and Text.
- The Position, when moving the Button i have to change the position of both so i Implemented a new Method which calls SetPosition from the Sprite and the Text.
- The SetSize just affects the Button so i just did using Sprite::SetSize;
- The angle affects both so i just implemented a new Method and hide the other two

The problem is here:
- The Origin: writing button.SetOrigin(-1,0) should set the Origin of the Button and writing button.SetTextOrigin should set the Origin of the text.
Should i just reimplement a Mehtod named SetTextOrigin and call Text::SetOrigin from there and hide the button.Text::SetOrigin or is there something like using Text::SetOrigin as SetTextOrigin?

Damn, after writing the last paragraph I feel like a dumb man, because that is obviously a good solution. but the question remains, is there something like using as?
Because, when i have that Method overloaded several times I'd have to reimplement each one of them, right?
Last edited on
Override the print member function in D and call A::print, B::print and C::print however you like (or not at all).

I'm having a hard time understanding your 'actual case' scenario.
Last edited on
My actual case scenario is this:

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
template <typename T>
class Origin
{
public:
    void SetOrigin(T x, T y) { __x = x; __y = y; }
    void SetOrigin(vector2<T> vect) { __x = vect.x; __y = vect.y; }

private:
    T __x;
    T __y;
}
class Sprite : Origin<float>
{
public:
    using Origin::SetOrigin;
}
class Text : Origin<int>
{
public:
    using Origin::SetOrigin;
}
class Button : Sprite, Text
{
public:
    using Sprite::SetOrigin;
    using Text::SetOrigin;
}


I have a button class that has a Text in it and a Texture for the button itself.
I'd like to set the Origin of the text in the button using btn.SetTextOrigin to make it obvious what origin is ment

The point is that i don't want to reimplement the Method for every overload.

this Question was allready answered in Stackoverflow, but thanks for the Help! :)
(http://stackoverflow.com/questions/28591700/change-method-name-in-derived-class)
Short Version: It is a XY Problem
Last edited on
Why do you use two different types for the location of two drawable things? Even if text rendering doesn't support floating-point precision, that's an implementation detail that shouldn't be exposed in the interface of your class.
I started to redesign everything, I realized that i did some very stupid things and this is one of the first things that changed(s, i'm still working on it)

I thought of Origin, Position and so on as things a Object has, so i just derived from them, when mergin Sprite and Text to Button i realized "DAMN what the fuck is happening" and changed one of them to float and one to int, tested if it worked and was happy for a short Time.

Now my Design looks something like this, Button will have Properties later as well.

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
template <typename T>
class Vector2
{
public:
    Vector2() : __mX(0), __mY(0) {}
    Vector2(T __X, T __Y) { set(__X, __Y); }

    void set(T __X, T __Y) { __mX = __X; __mY = __Y; }

    T x() const { return __mX; }
    T y() const { return __mY; }

private:
    T __mX;
    T __mY;
};

class LObject
{
public:
    LObject(const LObject* parent = nullptr, int PropertyId = -1) :
        __mParent(parent),
        __mId(PropertyId)
    { }

    virtual void PropertyChanged(int __PropertyId) const
    {
        std::cout << __PropertyId << std::endl;
    }

protected:
    const LObject* __mParent;
    int __mId;
};

class Property : protected LObject
{
public:
    Property(const LObject* parent = nullptr, int PropertyId = -1) :
        LObject(parent, PropertyId)
    {}
};

template <typename T>
class Position : protected Property
{
public:
    Position(const LObject* parent = nullptr, int PropertyId = -1) :
        Property(parent, PropertyId)
    {}
    Position(T __X, T __Y, const LObject* parent = nullptr, int PropertyId = -1) :
        Property(parent, PropertyId),
        __mPosition(__X, __Y)
    {}

    void set(T __X, T __Y)
    {
        __mPosition.set(__X, __Y);

        if(__mParent != nullptr)
            __mParent->PropertyChanged(__mId);
    }

    Vector2<T> operator()() const { return __mPosition; }

private:
    Vector2<T> __mPosition;
};

template <typename T>
class Origin : protected Property
{
public:
    Origin(const LObject* parent = nullptr, int PropertyId = -1) :
        Property(parent, PropertyId)
    {}
    Origin(T __X, T __Y, const LObject* parent = nullptr, int PropertyId = -1) :
        Property(parent, PropertyId),
        __mOrigin(__X, __Y)
    {}

    void set(T __X, T __Y)
    {
        __mOrigin.set(__X, __Y);

        if(__mParent != nullptr)
            __mParent->PropertyChanged(__mId);
    }

    Vector2<T> operator()() const { return __mOrigin; }

private:
    Vector2<T> __mOrigin;
};

class Angle : protected Property
{
public:
    Angle(const LObject* parent = nullptr, int PropertyId = -1) :
        Property(parent, PropertyId)
    {}
    Angle(float __Angle, const LObject* parent = nullptr, int PropertyId = -1) :
        Property(parent, PropertyId),
        __mAngle(__Angle)
    {}

    void set(float __Angle)
    {
        __mAngle = __Angle;

        if(__mParent != nullptr)
            __mParent->PropertyChanged(__mId);
    }

    float operator()() const { return __mAngle; }

private:
    float __mAngle;
};

template <typename T>
class BaseObject2D : public LObject
{
public:
    BaseObject2D() :
        position(this, __POSITION_ID),
        origin(this, __ORIGIN_ID),
        angle(this, __ANGLE_ID)
    {
    }

    Position<T> position;
    Origin<T> origin;
    Angle angle;

    virtual void PropertyChanged(int __PropertyId) { /* do stuff */ }

private:
    enum
    {
        __POSITION_ID,
        __ORIGIN_ID,
        __ANGLE_ID
    };
};

int main(void)
{
    BaseObject2D<float> obj;
    obj.position.set(50, 20);
    obj.origin.set(-1, 1);
    obj.angle.set(180);

    return 0;
}


Each object has properties, the properties have ID's and tell the parent object when something in them has changed.

Feels like i just improved my Programming skills by 2 Level lol

Just searching for a better way to deal with the PropertyID and then everything'll be fine
Last edited on
You should be aware, identifiers starting with a single underscore and capital letter, or identifiers containing two underscores in a row, are reserved for the implementation. You are not allowed to use such identifiers in your own code (though the compiler might accept it anyway).

http://stackoverflow.com/a/228797/1959975
Last edited on
Thats very important to know, thank you!
Topic archived. No new replies allowed.