Hilfe bei C++ Programm (ungelöst)

AW: Problem mit den Funktionen bei C++

ja, eine .net (c++) mit Buttens, list boxen usw....
 
AW: Problem mit den Funktionen bei C++

Warum machste das nicht in C++? Ich schätze mal, du nutzt Visual Studio. Da ist doch alles drin, um das in C/C++ zu machen. Läuft dann zwar nur unter windows, aber das haste mit .net auch (fast)


Was mich allerdings wundert ist, was bingo88 da schreibt zu den funktionen.

Wenn er schreibt

void funktionsname(){

//ich mach etwas

return irgendwas;
}

Dann darf das gar nicht funktionieren, da die Funktion ja als void Funktion geklariert ist, also ohne Rückgabewert. Eigentlich sollte das eine Fehlermeldung geben.

Genau wies einen Compilererror gibt, wenn man die Fuktion nicht void macht, sondern z.B. int und dann etwas anderszurück gibt als einen int, oder gar nichts zurück gibt.

Genau so siehts doch auch mit den Parametern aus.

Er lässt das ja z.B. frei, also

void meineFunktion();

Wenn man aber

void meineFunktion(void);

schreibt, dann darf man gar keinen Parameter übergeben, sonst gibt es einen compiler error.

Zumindest sollte das so sein, wenn ich jetzt nicht total aufm Holzweg bin.

Ich finde, du solltest dir die Sache mit Deklaration und Implementierung von Funktionen nochmals durchlesen. Insbesondere, wenn ich da an Headerfiles denke. Das sind wirklich basics. Die sollten sitzen.
 
AW: Problem mit den Funktionen bei C++

@Skysnake Ich meinte das Richtige, habe es aber nicht klar formuliert. Das sollte eigentlich so heißen: "return <wert> hat bei void Funktionen nichts zu suchen!". Ich bezog mich an der fraglichen Stelle darauf, dass die aufgerufene Funktion myFunction an sich void ist und daher keinen Rückgabewert liefert. Etwas untergegangen ist dabei allerdings die Tatsache, dass caller() auch void ist und somit ebenfalls nichts zurückgeben kann. Das wollte ich eigentlich mit dem Kommentar "// return <Wert>; macht bei einer void Funktion an sich schon wenig Sinn." ausdrücken, ist aber wohl was misslich. Der ganze Codeblock ist als so-soll-man-es-nicht-machen zu verstehen, ich hätte das wohl deutlicher kennzeichnen sollen.

Parameter an eine Funktion zu übergeben, die nicht in der Deklaration auftauchen, liefert zumindest in VS nen Linker-Error. Fehlende/falsche Rückgabewerte liefern entweder auch nen Error oder nur ne Warning, da bin ich mir jetzt grade nicht mehr sicher...
 
Zuletzt bearbeitet:
AW: Problem mit den Funktionen bei C++

Ich weiß doch, das du weißt, was geht und was nicht. ;) Es war halt in meinen Augen nur nicht klar für Crymes.

Ich glaub der gcc wirft da keinen Fehler, bin mir aber ganz ehrlich da auch nicht 100% sicher. Man kann so halt auf jeden Fall klar zwischen überladenen Funktionen unterscheiden, wenn man das void dazu nimmt.

Ich finds halt sauberer, wenn man Funktionen ohne Parameter das void als Parameter mit gibt ;)
 
AW: Problem mit den Funktionen bei C++

Es war halt in meinen Augen nur nicht klar für Crymes.
Da hast du Recht! Hab ich ja jetzt auch geschrieben, war was ungeschickt formuliert ^^

Ich glaub der gcc wirft da keinen Fehler, bin mir aber ganz ehrlich da auch nicht 100% sicher. Man kann so halt auf jeden Fall klar zwischen überladenen Funktionen unterscheiden, wenn man das void dazu nimmt.

Ich finds halt sauberer, wenn man Funktionen ohne Parameter das void als Parameter mit gibt ;)
Da ist was dran. Ich glaub der VS Klassenassistent macht das auch so (wenn man ihn denn nutzen möchte). Der macht aber auch nen paar andere Sachen:
Code:
class Blubb
{
public:
    Blubb(void);
    ~Blubb(void);

private:
    int m_var1;
    int m_var2;
    int m_var3;
};

// Vom VS Klassenassistenten generierte Initialsierungsliste
Blubb::Blubb(void)
: m_var1(0)
, m_var2(0)
, m_var3(0)
{
}
Das ist zwar jetzt ziemlich OT, aber ich bin da gestern drüber gestolpert und ich finde diese Formatierung der Initialisierungsliste irgendwie sehr unnatürlich...
 
Zuletzt bearbeitet:
AW: Problem mit den Funktionen bei C++

ähm...

Ich glaub da bist du jetzt auf nen ziemlichen Sonderfall gestoßen, der VIEL mehr macht, als du dir gerade Denkst :ugly:

Das erste Blubb ist ja für die Klasse, sozusagen wie das std halt ein Namespace

Das zweite Blubb ist dann der Funktionsname der Klasse blubb mit dem Parametern (void), also keinen, die du übergibst.

Das : m_var1(0) sollte dann sein, dass du etwas überlädst, was als Klassenvariable definiert ist. Zumindest heißt dass das :

(EDIT: (0) ist der Wert, mit dem du die vorher deklarierte Variable initialisierst. Das ist ja der Konstruktor für das Objekt der Klasse Blubb. Also nicht wirklich überladen, sondern eben der Wert mit dem die Variable initialisiert wird.)

Du hast in dem Fall halt die "m_var" in einem Headerfile definiert.

Ich seh so Code im Moment mehr oder weniger jeden Tag :fresse:

Mal ein "kleines" Beispiel:

Code:
/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ron Dreslinski
 *          Ali Saidi
 */

/**
 * @file
 * Declaration of a bus object.
 */

#ifndef __MEM_BUS_HH__
#define __MEM_BUS_HH__

#include <list>
#include <set>
#include <string>

#include "base/hashmap.hh"
#include "base/range.hh"
#include "base/range_map.hh"
#include "base/types.hh"
#include "mem/mem_object.hh"
#include "mem/packet.hh"
#include "mem/port.hh"
#include "mem/request.hh"
#include "params/Bus.hh"
#include "sim/eventq.hh"

class Bus : public MemObject
{
    /** Declaration of the buses port type, one will be instantiated for each
        of the interfaces connecting to the bus. */
    class BusPort : public Port
    {
        bool _onRetryList;

        /** A pointer to the bus to which this port belongs. */
        Bus *bus;

        /** A id to keep track of the intercafe ID this port is connected to. */
        int id;

      public:

        /** Constructor for the BusPort.*/
        BusPort(const std::string &_name, Bus *_bus, int _id)
            : Port(_name, _bus), _onRetryList(false), bus(_bus), id(_id)
        { }

        bool onRetryList()
        { return _onRetryList; }

        void onRetryList(bool newVal)
        { _onRetryList = newVal; }

        int getId() { return id; }

      protected:

        /** When reciving a timing request from the peer port (at id),
            pass it to the bus. */
        virtual bool recvTiming(PacketPtr pkt)
        { pkt->setSrc(id); return bus->recvTiming(pkt); }

        /** When reciving a Atomic requestfrom the peer port (at id),
            pass it to the bus. */
        virtual Tick recvAtomic(PacketPtr pkt)
        { pkt->setSrc(id); return bus->recvAtomic(pkt); }

        /** When reciving a Functional requestfrom the peer port (at id),
            pass it to the bus. */
        virtual void recvFunctional(PacketPtr pkt)
        { pkt->setSrc(id); bus->recvFunctional(pkt); }

        /** When reciving a status changefrom the peer port (at id),
            pass it to the bus. */
        virtual void recvStatusChange(Status status)
        { bus->recvStatusChange(status, id); }

        /** When reciving a retry from the peer port (at id),
            pass it to the bus. */
        virtual void recvRetry()
        { bus->recvRetry(id); }

        // This should return all the 'owned' addresses that are
        // downstream from this bus, yes?  That is, the union of all
        // the 'owned' address ranges of all the other interfaces on
        // this bus...
        virtual void getDeviceAddressRanges(AddrRangeList &resp,
                                            bool &snoop)
        { bus->addressRanges(resp, snoop, id); }

        // Ask the bus to ask everyone on the bus what their block size is and
        // take the max of it. This might need to be changed a bit if we ever
        // support multiple block sizes.
        virtual unsigned deviceBlockSize() const
        { return bus->findBlockSize(id); }

    };

    class BusFreeEvent : public Event
    {
        Bus * bus;

      public:
        BusFreeEvent(Bus * _bus);
        void process();
        const char *description() const;
    };

    /** a globally unique id for this bus. */
 [B][COLOR=red]   int busId;
    /** the clock speed for the bus */
    int clock;
    /** cycles of overhead per transaction */
    int headerCycles;
    /** the width of the bus in bytes */
    int width;[/B]
    /** the next tick at which the bus will be idle */
    Tick tickNextIdle;

    Event * drainEvent;

usw....
Code:
/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

/**
 * @file
 * Definition of a bus object.
 */

#include <algorithm>
#include <limits>

#include "base/misc.hh"
#include "base/trace.hh"
#include "debug/Bus.hh"
#include "debug/BusAddrRanges.hh"
#include "debug/MMU.hh"
#include "mem/bus.hh"

Bus::Bus(const BusParams *p)
    : MemObject(p),[B][COLOR=red] busId(p->bus_id), clock(p->clock),
      headerCycles(p->header_cycles), width(p->width)[/B], tickNextIdle(0),
      drainEvent(NULL), busIdle(this), inRetry(false), maxId(0),
      defaultPort(NULL), funcPort(NULL), funcPortId(-4),
      useDefaultRange(p->use_default_range), defaultBlockSize(p->block_size),
      cachedBlockSize(0), cachedBlockSizeValid(false)
{
    //width, clock period, and header cycles must be positive
    if (width <= 0)
        fatal("Bus width must be positive\n");
    if (clock <= 0)
        fatal("Bus clock period must be positive\n");
    if (headerCycles <= 0)
        fatal("Number of header cycles must be positive\n");
    clearBusCache();
    clearPortCache();
}

usw...
Den wichtigen Teil hab ich mal Rot gemacht. Wie du siehst wird das durchaus verwendet. Ich muss aber auch sagen, ich bin da 100% noch nicht durch gestiegen, wie das alles jetzt zu verstehen ist, wobei ich auch sagen muss, ich hab noch das Problem, das ich gemischten C/C++&Python Code habe :fresse: Da wirds dann SEHR interessant, den Code zu verstehen bei, was warens?, 250.000-500.000 Zeilen Code :ugly:
 
AW: Problem mit den Funktionen bei C++

Nochmal zum void + return;
Dieses Post bezieht sich auf Skysnake's Aussage:
Dann darf das gar nicht funktionieren, da die Funktion ja als void Funktion geklariert ist, also ohne Rückgabewert. Eigentlich sollte das eine Fehlermeldung geben.

Genau wies einen Compilererror gibt, wenn man die Fuktion nicht void macht, sondern z.B. int und dann etwas anderszurück gibt als einen int, oder gar nichts zurück gibt.

Das klappt theoretisch schon! Bingo88 hatte ja bei dem Code keinen Interger, Float oder sonst was zurückgegeben sondern eben eine Funktion, daher läuft das auch ohne Error.
Schließlich gibt int eine Zahl zurück und bei void kommt eben eine void zurück. Dass das natürlich wenig Sinn macht ist die andere Sache.
Visual wird da vermutlich rummeckern von wegen Rekursiv bla aber vom Syntax her ist da kein Fehler drin.
 
AW: Problem mit den Funktionen bei C++

Ich meinte hier schon die Initialisierungsliste (sprich m_varX ist Member der Klasse Blubb und keine globale Var). Ich mache aus Gewohnheit viel mit der IL, daher ist mir der Krempel recht gut vertraut. Mir ging es eigentlich um die Formatierung (aber danke für die ausführliche Erklärung :D). Ich hätte es halt eher so formatiert:
Code:
Blubb::Blubb(void) :
    m_var1(0),
    m_var2(0),
    m_var3(0)
{
}
Aber Visual Studios Autoformat macht dann komische Sachen damit :(

Edit: Hab mal meinen Code von vorher ergänzt, sodass es nun klarer sein sollte.
 
Zuletzt bearbeitet:
AW: Problem mit den Funktionen bei C++

Zur frage weiter vorn: Ich wollte das in ferner Zeit in VS mit c++ und .net schreiben
 
AW: Problem mit den Funktionen bei C++

Naja, schau dir mal meinen Code an, das ist auch nicht besser formatiert. :D

PS: Was ist jetzt der Unterschied zwischen nem Member und ner globalen Variable? :ugly: Jetzt ernst gemeint. Ich weiß auch nicht jedes Detail, und hatte vorher damit recht wenig zu tun.

Verhält sich doch ähnlich, nur das eben wenn ich ne echte globale Variable habe über die Objektinstanzen diese als const deklarieren müsste, was ja in meinem Code meistens der Fall ist. Und bei Member kanns halt auch nur einfach innerhalb des Objekts was "globales" sein. Oder überseh ich da was?

Sorry fürs highchecken des Threads :lol:
 
AW: Problem mit den Funktionen bei C++

Irgendwie habe ich deinen Code falsch gedeutet, das "globally unique" im Kommentar über einer der Variablen zusammen mit den verschachtelten Klassen hat mich verwirrt. Da gibt es keine globale Variable, das war totaler Quatsch von mir! Die von dir markierten Stellen (int busId, etc.) sind normale public Membervariablen der Klasse Bus. Mit einer Initialisierungsliste kann man ja eh nur auf Member einer Klasse zugreifen, wie komme ich bloß auf so einen Müll :ugly: Naja, jedenfalls ist das ein typisches Beispiel für die Verwendung einer Initialisierungsliste.

@Crymes: Ich könnte dir für grafische Oberflächen auch Qt empfehlen, das ist "normales" C++ und du kannst denselben Code auch für Linux nutzen. Ich persönlich finde das einfacher als C++/CLR.
 
Zuletzt bearbeitet:
AW: Problem mit den Funktionen bei C++

Ja, ich hab Qt auch schon verwendet. Das geht ganz gut, aber ist teilweie ziemlich hartet Tobak. Ich empfehle dir auf jeden Fall die Entwicklungstools dazu zu verwenden!!!

Und ich hoffe du lässt Multithread Programmierung dazu weg.

Ich habs mit MPI, OpenMP und PThreads kombinieren dürfen, und teils war das echt ugly.:ugly:

bingo88:
Das mit der "globalen" Variable hab ich gesagt, weil ich das Konstrukt vorher noch nie gesehen hatte, aber so interpretiert hatte. Aber gut zu wissen, dass die Dinger Membervariablen heißen.

Meine Erklärung bzgl der Zugriffe etc. hat doch aber gestimmt oder? Halt nur den richtigen Namen nicht gekannt.

Kannste eventuell noch was dazu sagen, warum man das mit variablen_name(irgendwas) macht, und was das bedeutet?

Wäre echt nett, weil der Code funktioniert, ich kann ihn erweitern etc. haber wäre schon gut zu wissen, dass das auch wirklich alles so passt. Auf das Konstrukt trifft man eben normal nicht. -.-
 
AW: Problem mit den Funktionen bei C++

Kannste eventuell noch was dazu sagen, warum man das mit variablen_name(irgendwas) macht, und was das bedeutet?
Natürlich.

Nehmen wir mal wieder unsere Klasse Blubb:
Code:
class Blubb
{
public:
    Blubb(void);
    ~Blubb(void);

private:
    int m_var1;
};
Du hast bei dieser Klasse zwei Möglichkeiten deine Membervariable m_var1 zu initialisieren (Membervariable heißt einfach nur, dass sie an eine Instanz der Klasse gebunden ist; gibt ja noch globale und statische Variablen):
Code:
// "Klassisch" im Konstruktor
Blubb::Blubb(void)
{
    m_var1 = 0;
}
Code:
// Initialisierungsliste
Blubb::Blubb(void) :
m_var1(0)
{
}
Die beiden Varianten sind hier vollkommen äquivalent.

Anders sieht das hier aus:
Code:
class Blubb
{
public:
    Blubb(void);
    ~Blubb(void);

private:
    const int m_var1; // die ist nun const!
};
Das Initialisieren im Konstruktor klappt jetzt nicht mehr, da der Body vom Konstruktor aufgerufen wird, nachdem die Variablen initialisiert wurden! (Klingt was komisch, hängt aber mit den internen Abläufen bei C++ zusammen; siehe ganz unten).
Code:
Blubb::Blubb(void)
{
    m_var1 = 0; // oops, m_var1 ist const :(
}
Hier musst du jetzt die Initialisierungsliste verwenden, da diese vor dem eigentlichen Konstruktor durchlaufen wird:
Code:
Blubb::Blubb(void) :
m_var1(0)
{
    // so ist das ok, m_var1 hat jetzt den Wert 0
}
Richtig spannend wird das aber eigentlich erst, wenn du komplexe Datentypen (andere Klassen) als const-Membervariablen hast.
Code:
class A
{
public:
    A(int param) :
        m_param(param)
    {
        // hier ginge auch m_param = param!
    }

    ~A(void)
    {
    }

private:
    int m_param; // nicht const
};

class B
{
public:
    B(void) :
       m_a(1337) // hier wird der Konstruktor von A mit param = 1337 aufgerufen
    {
        // m_a(1337) geht nicht, da m_a const ist!
    }

    ~B(void)
    {
    }

private:
    const A m_a; // const
};
Bei dem letzten Beispiel kommt noch hinzu, dass die Klasse A keinen parameterlosen Standardkonstruktor besitzt, daher müsstest du hier mittels der Initialisierungsliste den Konstruktor von A so oder so aufrufen.

Die Syntax ist identisch mit dem Aufruf von Basisklassenkonstruktoren, da das Problem dahinter ähnlich ist.

Du kannst das also ruhig weiter verwenden, das ist kein Problem. Wie gesagt, bei konstanten Membervariablen oder fehlendem Standardkonstruktor hast du eh keine andere Wahl und musst das so machen.

Edit: Hier ein Beispiel, was ich mit den internen Abläufen meine.
Code:
class Blubb
{
public:
    Blubb(void);
    ~Blubb(void);

private:
    std::string m_text;
};


Blubb::Blubb(void)
{
    m_text = "Hallo, Welt!";
}
Was hier im Konstruktor Blubb::Blubb(void) passiert ist folgendes:
Zuerst wird ein leeres m_text Objekt erzeugt (also der Standardkonstruktor von std::string aufgerufen).
Standardkonstruktoren werden immer dann aufgerufen wenn a) kein Eintrag in der Initialisierungsliste vorhanden und b) ein Standardkonstruktor verfügbar ist.

Danach erfolgt eine Zuweisung des Texts "Hallo, Welt!" an m_text. Hier wird also zuerst ein Objekt angelegt und anschließend direkt wieder überschrieben. Bei Objekten, die eine komplexe und damit teure Initialisierung haben, ist das natürlich Gift für die Performance!

Anders sieht es hier aus:
Code:
Blubb::Blubb(void) :
m_text("Hallo, Welt!")
{
}
Hier wird direkt der Konstruktor von std::string mit dem Parameter "Hallo, Welt!" aufgerufen, was natürlich billiger ist.
 
Zuletzt bearbeitet:
AW: Problem mit den Funktionen bei C++

Hab mich jetzt mal wieder mit dem Programm beschäftigt, scheiter aber nach wie vor wegen nicht gewollten beendens.
Kann mir einer nochmal sagen, was ioch jetzt mit dem bool und dem while falsch gemacht hab?

Es geht genauer um die funktionen main und abfrage.Anhang anzeigen 521724
 
Zurück