Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

1

17.04.2007, 20:28

Returnwerte "überladen" - Wie geht man da am Beste

Der Titel sagts eigentlich schon. Ich habe eine Methode die den operator [] für eine Klasse implementiert. Es handelt sich dabei um einen "Cfg Parser" der Ini Style Dateien ausliest. Die Handhabung sieht in Code ungefähr so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
int main (void)
{
    GX::CfgFile cfg("data\\config.cfg");
    cfg.parse();

    std::string a = cfg["Section"]["eins"];

    return (0);
}
Ich würde den operator [] nun gerne so "überladen", dass er wenn a z.B. ein int wäre, auch einen int zurück gegeben wird (wenns nicht hinhaut werf ich ne Exception). Scheint aber nicht zu gehen.

Muss ich nun wirklich mit so tollen Methoden a la getValueAsInt(std::string key) arbeiten? Oder gibts da auch was "eleganteres"?

Edit: Oo, die Überschrift wird immer kastriert

Phil_GDM

Alter Hase

Beiträge: 443

Wohnort: Graz

Beruf: Student-Softwareentwicklung u. Wissensmanagement

  • Private Nachricht senden

2

17.04.2007, 20:34

Ja du musst es so machen. Return-typen von Funktionen dürfen in C++ nicht überladen werden.

mfg Philipp

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

3

17.04.2007, 20:36

Du könntest es mit Templates machen.

int i = cfg.get<int>("test");

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

4

17.04.2007, 20:39

Vorallem, woher soll er denn wissen, was du überhaupt für ein Typen haben willst, weil nicht immer ist es offen ersichtlich ;). Aber du könntest so sachen wie Variant nutzen^^. Gibt es irgendwo in der MSXML API(glaube ich zumindest). Oder du schreibst dir eine Struktur mit einer union drinne.

(Zwischenfrage: wird union eigentlich noch von irgendwen praktisch genutzt, oder ist das nur noch was für Speicheridealisten und Leute, die für andere Plattform als PC/Mac usw. programmieren?)


[EDIT]im definitly too slow >.< [/EDIT]
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

5

17.04.2007, 21:03

In Davids Tribase Engine gibt es eine praktische Anwendung dafür:

C-/C++-Quelltext

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
class TRIBASE_API tbVector3
{
public:
    // Variablen

    union
    {
        struct
        {
            float x;    // Koordinaten

            float y;
            float z;
        };

        struct
        {
            float u;    // Texturkoordinaten

            float v;
            float w;
        };

        float       c[3];       // Array der Koordinaten

        D3DVECTOR   vD3DVector; // Vektor in Form eines Direct3D-Vektors

    };

    ...
};


Eine praktische Möglichkeit die gleichen Variablen auf verschiedene Weisen anzusprechen.

Zum Topic:

Ich würde da einheitlich bleiben und immer strings zurück geben lassen und bei gegebenen Anlass dann in eine Zahl parsen.

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

6

17.04.2007, 21:20

Du könntest auch eine Klasse (z.b. Item) schreiben, die die Lösung allgemein enthält - jetzt noch Castingoperatoren zu allen gewünschten Typen dazu und fertig ist die überdimensionale aber in der Anwendung bequeme Lösung^^

Hoffe ich hab jetzt keinen Denkfehler bei der Problemlösung^^

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

7

17.04.2007, 21:59

Meine Idee:

C-/C++-Quelltext

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
#include <iostream>
#include <vector>
#include <algorithm>

struct ini_item_base
{
    virtual ~ini_item_base() = 0;

    virtual operator int() const
    {
        throw std::bad_cast( "cannot cast to int" );
    }

    virtual operator std::string() const
    {
        throw std::bad_cast( "cannot cast to string" );
    }

    // Weitere konvertierungs operatoren

};

ini_item_base::~ini_item_base()
{}

template< typename T >
struct ini_item;

template<>
struct ini_item< int >
    : ini_item_base
{
    int value;

    ini_item( int val )
        : value( val )
    {}

    operator int() const
    {
        return value;
    }

    // Weitere konvertierungs operatoren

};

template<>
struct ini_item< std::string >
    : ini_item_base
{
    std::string value;

    ini_item( std::string val )
        : value( val )
    {}

    operator std::string() const
    {
        return value;
    }

    // Weitere konvertierungs operatoren

};

namespace
{
    struct deleter
    {
        template< typename T >
        void operator()( T*& ptr )
        {
            delete ptr;
            ptr = 0;
        }
    };
}

struct foo
{
    typedef std::vector< ini_item_base* > list_type;

    foo()
    {
        // Mal zwei Beispieleintraege 

        list.push_back( new ini_item< int >( 100 ) );
        list.push_back( new ini_item< std::string >( "Hallo Welt" ) );
    }

    ~foo()
    {
        std::for_each( list.begin(), list.end(), deleter() );
    }

    const ini_item_base& operator[]( int x ) const
    {
        return *list.at( x );
    }

private:
    list_type list;
};

int main()
{
    foo x;
    int y;
    std::string z;

    try
    {
        y = x[ 0 ];
        z = x[ 1 ];

        // std::string blubb = x[ 0 ]; // <- Wirft ein std::bad_cast

    }
    catch ( std::bad_cast& e )
    {
        std::cout << "Exception: " << e.what() << std::endl;
    }

    std::cout << y << " " << z << std::endl;
    std::cin.get();
}
@D13_Dreinig

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

8

17.04.2007, 22:25

Ich dachte schon meine Idee wäre kompliziert :lol:

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

9

17.04.2007, 22:25

Zitat von »"grek40"«

Ich dachte schon meine Idee wäre kompliziert :lol:


Ha, man sieht: es geht immer noch komplizierter! ;-P
@D13_Dreinig

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

10

18.04.2007, 14:27

hmm irgendwie finde ich es immer wieder klasse, wie man bei dem Versuch etwas einfacher zu machen auf die tollsten Lösungen kommt. In der Zeit, die man fürs Überlegen und Programmieren gebraucht hat, hätte man GetInt(dank Intellisense) locker ein paar tausend mal runtertippen können.....
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Werbeanzeige