switch and visibility

Pages: 12
Hi@all

I use switch to create a template class at runtime but once the switch is finished the class is no longer available (the pointer is destructed).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
switch (base){
  case 1 :
    {figura<int> * fig  = get_figure<int>(file);}
    break;
  case 2 :
    {figura<float> * fig  = get_figure<float>(file);}
    break;
  case 3 :
    {figura<double> * fig  = get_figure<double>(file);}
    break;
  case 4 :
    {figura<long double> * fig = get_figure<long double>(file);}
    break;
    }
fig->scemochilegge();


How can I fix this?

Thanks in advantage.

GB
What about something like boost::any, template polymorphism and such?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
figura<float> * fig; // declare fig in a scope that will last longer than the switch() statement.

switch (base){
  case 1 : { fig = get_figure<int>(file); }
  break;
  case 2 : { fig = get_figure<float>(file); }
  break;
  case 3 : { fig = get_figure<double>(file); }
  break;
  case 4 : { fig = get_figure<long double>(file); }
  break;
}

fig->scemochilegge();
Last edited on
I've just noticed the
fig->scemochilegge()
part :^/
@Bazzy: sorry I can't understand what you mean =((

@Galik: I've just tryied it but figura<float> is different from figura<int> so there was an error like

cannot convert 'figura<int>*' to 'figura<float>*' in assignment

for

int
double
long double.

Thanks a lot =D
TiaSorella wrote:
I've just tryied it but figura<float> is different from figura<int> so there was an error like

Well you are not going to be able to assign anything other than a figura<float>*, or a subclass thereof to your variable fig. What are you trying to do? Can you post the rest of your code, or at least get_figure<>()?
I have to change the "base" of the figure at runtime.

#EDIT: U have PM
Last edited on
Templates are not used for runtime polymorphism, which appears to be what you are doing with your
switch statement. Although there are solutions, I would recommend eschewing the template-based
approach.
@jsmith : my teacher tell me I have to do it...is there other solution?
@TiaSorella
I have looked at your code and you are trying to do things using templates that they were not designed for. Whatever your teacher is asking, I don't think he is expecting you to solve it in this way. Templates can be useful in this but I think you need to rethink your approach. What exactly is the teacher asking you to do?
Ah, I would have said "What's wrong with this here?"

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
class base_fig
{
public:
    virtual void scemochilegge(){}
    //this actually means
    //"whoever reads this is stupid"
};

template <class T>
class figura: public base_fig {/*...*/};

int main()
{
    //...

    base_fig * pbfig;
    
    switch (base)
    {
        case 1 : { pbfig = get_figure<int>(file); }
        break;
        case 2 : { pbfig = get_figure<float>(file); }
        break;
        case 3 : { pbfig = get_figure<double>(file); }
        break;
        case 4 : { pbfig = get_figure<long double>(file); }
        break;
    }

    pbfig->scemochilegge();

    //...
}

...but then I saw Galik's post. So, yes, what exactly is it that you are asked to do?
Last edited on
a program that keep up infos from a file (the figure and the points in a [-10,10]^2 square) and let choose the base to use for work.

Using the monte carlo tecnique must clacolate an approximate area and comparate it with the analitic one.

One my friend simply used #DEFINE and re-compilate the program at every base but it's not too smart...
@master: you true..sorry for the name but it not was important for my problem...

I MUST template the class base_fig (or figura in my program) because it conteins a template method =(
Could you post your code here? It would also be useful if you posted the contents of the file.
Use code tags for your code -> [code]your code here[/code].
here you are bwoys =)

10kb of zip files =P

http://www.megaupload.com/?d=UPM30WYJ
It seems to me that the abstract factory pattern could be of use here.
The concrete factories would be template instantiations for specific primitive types.

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

class Shape {};

class Triangle: public Shape {};
class Circle: public Shape {};

template <class T>
class TriangleT: public Triangle {};
template <class T>
class CircleT: public Circle {};

class MyApp
{
public:
    virtual ~MyApp() {}
    virtual Triangle * NewTriangle() {return 0;}
    virtual Circle * NewCircle() {return 0;}
    virtual Shape * get_shape(istream & is) {return 0;}
    virtual void monte_carlo(unsigned int points, Shape * shape) {}
};

template <class T>
class MyAppT: public MyApp
{
public:
    virtual Triangle * NewTriangle()
    {
        return new TriangleT<T>;
    }

    virtual Circle * NewCircle()
    {
        return new CircleT<T>;
    }

    virtual Shape * get_shape(istream & is)
    {
        Shape * new_shape;
        cout << "get_shape" << endl;
        //do stuff
        //...
        return new_shape;
    }

    virtual void monte_carlo(unsigned int points, Shape * shape)
    {
        cout << "monte_carlo" << endl;
        //do stuff
        //...
    }
};

int main()
{
    MyApp * my_app;
    int type;
    unsigned int points;

    cout << "choose your type:\n";
    cout << "(1) int\n";
    cout << "(2) float\n";
    cout << "(3) long\n";
    cout << "(4) double\n";
    cout << endl;

    cin >> type;

    switch (type)
    {
        case 1: my_app=new MyAppT<int>; break;
        case 2: my_app=new MyAppT<float>; break;
        case 3: my_app=new MyAppT<long>; break;
        case 4: my_app=new MyAppT<double>; break;
    }

    cout << "enter number of points: ";
    cin >> points;

    ifstream fin;
    fin.open("data.txt");

    while (true)
    {
        Shape * shape;
        shape=my_app->get_shape(fin);
        if (!fin) break;
        my_app->monte_carlo(points,shape);
        //other stuff here
        //...
    }

    delete my_app;
    return 0;
}

EDIT: Though, I'm not sure that's what your teacher had in mind...
Last edited on
u're a boos ;)

when I have little time I'm gonna try this out!
@master....there is a problem =((

I have to use a method area() that must be templated...I put it into my template class : figure, triangle, circle etc.

But if I use a non-templated class shape I can't declare in it a method " virtual void area()= 0 " [there is a problem of overrinding when i declare " T area() " into SahpeT ...

An other solution will be to put a method " T area( shape *) " into MyAppT but it will be longer and little uggly..


Tanks a lot! =D
The simple solution is to make area print the result instead of returning it. I think this would be enough for this exercise. There are probably other ways, but I believe all of them are ugly. I'll keep thinking though... And maybe someone else knows better...
yeah but i have to do any computation whit the analitycs area.

Anyway I think it's enought to use long double as return type of the area() method and casting (C's style) the value before returning directly into the implementetion of area() in triangolo.cc etc.

I don't know why I haven't thought it yet
Pages: 12