using object of derived class instead object of base class in argument of function in derived class

Our apologies if the title is not appropriate. How can i solve below problem?

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
class IA
{
};
class IB : public IA
{
};
class B : public IB
{
};
class IX
{
public:
	virtual void x(IA *a) = 0;
};
class X : public IX
{
public:
	//virtual void x(IA *b) {}
	virtual void x(IB *b)
	{
		cout << "ok" << endl;;
	}
};

void main()
{
	B b;
	X x;
	x.x(&b);
}
Last edited on
Works fine if you actually override x in X instead of trying to overload it.

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
// http://ideone.com/EoMbuV
#include <iostream>

class IA
{
};

class IB : public IA
{
};

class B : public IB
{
};

class IX
{
public:
    virtual void x(IA*) = 0;
};


class X : public IX
{
public:
    virtual void x(IA*)
    {
        std::cout << "ok\n";
    }
};

int main()
{
    B b;
    X x;
    x.x(&b);
}
Many thanks for your reply cire:
In fact, in class IX, we want to design x such that its argument is IA* or T* where T is any type which is derived from IA:

1
2
3
4
5
 class IX
{
public:
	virtual void x(IA * or (Any type which extends IA)*) = 0;
};
Does this sort of do what you require?

If not, it might help if you can give us an example of the kind of functionality you require the mechanism for.

Andy

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
#include <iostream>
#include <string>
using namespace std;

class IShape
{
public:
    virtual string getType() const = 0;
};

class ICircle : public IShape
{
public:
    virtual double getRadius() const = 0;
};

class IRect : public IShape
{
public:
    virtual double getWidth() const = 0;
    virtual double getHeight() const = 0;
};

class Circle : public ICircle
{
private:
    double radius_;
public:
    Circle() : radius_(0) {}
    Circle(double r) : radius_(r) {}
    string getType() const { return "circle"; }
    double getRadius() const { return radius_; }
};

class Rect : public IRect
{
private:
    double width_;
    double height_;
public:
    Rect() : width_(0), height_() {}
    Rect(double w, double h) : width_(w), height_(h) {}

    string getType() const { return "rect"; }
    double getWidth() const { return width_; }
    double getHeight() const { return height_; }
};

class ITester
{
public:
    virtual void test(const IShape *pshape) const = 0;
};

class Tester : public ITester
{
public:
    virtual void test(const IShape *pshape) const
    {
        const IRect* prect = dynamic_cast<const IRect*>(pshape);
        if(nullptr != prect)
        {
            cout << "Shape is a rect\n"
                 << "width  = " << prect->getWidth()  << "\n"
                 << "height = " << prect->getHeight() << "\n";
        }
        else
        {
            const ICircle* pcircle = dynamic_cast<const ICircle*>(pshape);
            if(nullptr != pcircle)
            {
                cout << "Shape is a circle\n"
                     << "radius = " << pcircle->getRadius() << "\n";
            }
            else
            {
                cout << "Shape is an unhandled type\n";
            }
        }
    }
};

void DoTest(const IShape* pshape)
{
    Tester tester;
    tester.test(pshape);
}

int main()
{
    Circle circle(3);
    Rect rect(5, 8);

    DoTest(&circle);
    cout << "\n";
    DoTest(&rect);
    cout << "\n";

    return 0;
}
dear andywestken, many thanks for your help.
These codes let us to check types in running-time:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Rec_Tester : public ITester
{
public:
	virtual void test(const IShape *pshape) const
	{
		const IRect* prect = dynamic_cast<const IRect*>(pshape);
		assert(prect);
		cout << "Shape is a rect\n"
			<< "width  = " << prect->getWidth() << "\n"
			<< "height = " << prect->getHeight() << "\n";
	}
};

class Circle_Tester : public ITester
{
public:
	virtual void test(const IShape *pshape) const
	{
		const ICircle* pcirc = dynamic_cast<const ICircle*>(pshape);
		assert(pcirc);
		cout << "Shape is a circle\n"
			<< "radius = " << pcirc->getRadius() << "\n";
	}
};


Now, is it possible to check same in compiling-time like below-coming codes (without adding other virtual functions in Itester. it is no problem if the format of test function is changed)?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Rec_Tester : public ITester
{
public:
	virtual void test(const IRect *prect) const
	{
		cout << "Shape is a rect\n"
			<< "width  = " << prect->getWidth() << "\n"
			<< "height = " << prect->getHeight() << "\n";
	}
};

class Circle_Tester : public ITester
{
public:
	virtual void test(const ICircle *pcirc) const
	{
		cout << "Shape is a circle\n"
			<< "radius = " << pcirc->getRadius() << "\n";
	}
};


You can't derive from ITester and then change the type of parameter that its function test() takes. This is exactly the same issue which came up earlier, with IX's function x(), and you were told it was not possible. It's still not possible!

I am unclear why you want to use interfaces (assuming the I prefix is for interface.) Why do Rec_Tester and Circle_Tester need to derive from ITester?

To fully answer your question we really need to understand what underlying problem you're trying to solve with this approach.

cire has already mentioned operloading; that might just be a better approach. And then there are templates (and template specialization.) Etc.

Andy
Topic archived. No new replies allowed.