Advice implementing Decorator Pattern?

Hi, I'm dealing with the exact same issue as the OP here: http://stackoverflow.com/questions/5432288/how-to-avoid-c-cast-for-specific-class-methods-design-pattern

and to summarize that link, basically I need to access a specific class method of a derived object when I am only given a base pointer. I would like to avoid using static_cast, even though I know this would solve my problem.

Following links given from that post, I determined that the Decorator Pattern (https://en.wikipedia.org/wiki/Decorar_pattern) could help solve my problem. But that's just my guess; I'm not sure how to implement the Decorator Pattern to access a specific method to a derived class from a base pointer.

The link only provides a Java example, and I have spent maybe 10 hours working with Java two years ago, so while I converted the example given to C++, if somebody could take a look at it and see if there are any optimizations, that would be helpful.

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
// Decorator Pattern.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>

//so you have an abstract class
class Window{
public:
	virtual void Draw() = 0;
	virtual std::string GetDescription() = 0;
};

class SimpleWindow : public Window{
public:
	virtual void Draw(){

	}
	std::string GetDescription(){
		return std::string("Simple window.\n");
	}
};

class WindowDecorator : public Window{
public:
	WindowDecorator(Window *window){
		windowToBeDecorated = window;
	}
	virtual void Draw(){
		windowToBeDecorated->Draw();
	}
	virtual std::string GetDescription(){
		return windowToBeDecorated->GetDescription();
	}
protected:
	Window *windowToBeDecorated;
};

class VerticalScrollBarDecorator : public WindowDecorator{
public:
	VerticalScrollBarDecorator(Window *window) : WindowDecorator(window){

	}
	virtual void Draw(){
		WindowDecorator::Draw();
		DrawVerticalScrollBar();
	}
	std::string GetDescription(){
		return WindowDecorator::GetDescription() + " including vertical scrollbars.\n";
	}
private:
	void DrawVerticalScrollBar(){

	}
};

class HorizontalScrollBarDecorator : public WindowDecorator{
public:
	HorizontalScrollBarDecorator(Window *window) : WindowDecorator(window){

	}
	virtual void Draw(){
		WindowDecorator::Draw();
		DrawHorizontalScrollBar();
	}
	std::string GetDescription(){
		return WindowDecorator::GetDescription() + " including horizontal scrollbars.\n";
	}
private:
	void DrawHorizontalScrollBar(){

	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	Window *decoratedWindow = new HorizontalScrollBarDecorator(new VerticalScrollBarDecorator(new SimpleWindow()));
	std::cout << decoratedWindow->GetDescription();
	system("pause");
	return 0;
}


So how can I extrapolate this Decorator Pattern so that I can create a Base pointer, assign it a Derived value, then access a Derived method via that Base value, without using static_cast or virtual functions?
> without using static_cast or virtual functions?

Without using any cast. Using virtual functions.
In this example, the decorator owns the decorated window.

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
#include <iostream>
#include <memory>

class Window{

    public:
        virtual ~Window() = default ;
        virtual void Draw() const = 0;
};

class SimpleWindow : public Window{

    public:
        ~SimpleWindow() { std::cout << "SimpleWindow::destructor\n" ; }
        virtual void Draw() const override { std::cout << "draw simple window\n" ; }
};

class WindowDecorator : public Window{
    public:
        // the ownership of the decorated window is transferred to WindowDecorator
        WindowDecorator( std::unique_ptr<Window>&& window) : windowToBeDecorated( std::move(window) ) {}

        virtual void Draw() const override { if(windowToBeDecorated) windowToBeDecorated->Draw(); }

    protected:
        std::unique_ptr<Window> windowToBeDecorated;
};

class VerticalScrollBarDecorator : public WindowDecorator{
    public:
        using WindowDecorator::WindowDecorator ;
        ~VerticalScrollBarDecorator() { std::cout << "VerticalScrollBarDecorator::destructor\n" ; }

        virtual void Draw() const override {
            WindowDecorator::Draw();
            DrawVerticalScrollBar();
        }

    private:
        void DrawVerticalScrollBar() const { std::cout << "draw a vertical scrollbar\n" ; }
};

class HorizontalScrollBarDecorator : public WindowDecorator{
    public:
        using WindowDecorator::WindowDecorator ;
        ~HorizontalScrollBarDecorator() { std::cout << "HorizontalScrollBarDecorator::destructor\n" ; }

        virtual void Draw() const override {
            WindowDecorator::Draw();
            DrawHorizontalScrollBar();
        }

    private:
        void DrawHorizontalScrollBar() const { std::cout << "draw a horizontal scrollbar\n" ; }
};

int main()
{
    std::unique_ptr<Window> pw = std::make_unique<SimpleWindow>() ;
    pw->Draw() ;
    std::cout << '\n' ;

    // the ownership of the decorated window is transferred to WindowDecorator
    pw = std::make_unique<VerticalScrollBarDecorator>( std::move(pw) ) ;
    pw->Draw() ;
    std::cout << '\n' ;

    // the ownership of the decorated window is transferred to WindowDecorator
    pw = std::make_unique<HorizontalScrollBarDecorator>( std::move(pw) ) ;
    pw->Draw() ;
    std::cout << '\n' ;
}

draw simple window

draw simple window
draw a vertical scrollbar

draw simple window
draw a vertical scrollbar
draw a horizontal scrollbar

HorizontalScrollBarDecorator::destructor
VerticalScrollBarDecorator::destructor
SimpleWindow::destructor

http://coliru.stacked-crooked.com/a/8034d25537962572
Topic archived. No new replies allowed.