Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Warum meckert mein Compiler:member function already defined

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
06.09.2007, 09:51 Uhr
ProgramPaula



Habe folgenden Code (aus C++ in 21 Tagen):

Problem: Der Compiler (MS Visual Stuidio 2005)meckert:
string.cpp(39) : error C2535: 'String::String(void)' : member function already defined or declared
Schnall ich nicht, da ich in der Klassendeklaration den Konstruktor deklariere. Und weiter unten dann die Implementierung erfolgt. Habe ich eine falsche Compilereinstellung???


C++:
#include <iostream>
//#include <string>

using std::cin ;
using std::cout ;
using std::endl ;

class String
{
public:
// Konstruktoren
    String();
String(const char *const);
String(const String &);
~String();

// ueberladene Operatoren
char & operator[](int offset);
char operator[](int offset) const;
String operator+(const String&);
void operator+=(const String&);
String & operator= (const String &);

// Allgemeine Zugriffsfunktionen
int GetLen()const { return itsLen; }
const char * GetString() const { return itsString;
// static int ConstructorCount;

private:
String (int);         // Privater Konstruktor
char * itsString;
unsigned short itsLen;

};

// Standardkonstruktor erzeugt String von 0 Bytes Laenge
String::String()
{
itsString = new char[1];
itsString[0] = '\0';
itsLen=0;
// cout << "\tString-Standardkonstruktor\n";
// ConstructorCount++;
}

// Privater (Hilfs-) Konstruktor, der nur von Methoden
// der Klasse zum Erzeugen neuer Null-Strings der
// erforderlichen Groeße verwendet wird.
String::String(int len)
{
itsString = new char[len+1];
for (i = 0; i<=len; i++)
itsString[i] = '\0';
itsLen=len;
// cout << "\tString(int)-Konstruktor \n";
// ConstructorCount++;
}

//Konvertiert ein Zeichen-Array in einen String
String::String(const char * const cString)
{
itsLen = strlen(cString);
itsString = new char[itsLen+1];
for (i = 0; i<itsLen; i++)
itsString[i] = cString[i];
itsString[itsLen]='\0';
// cout << "\tString(char*)-Konstruktor\n";
// ConstructorCount++;
}

// Kopierkonstruktor
String::String (const String & rhs)
{
itsLen=rhs.GetLen();
itsString = new char[itsLen+1];
for (int i = 0; i<itsLen;i++)
itsString[i] = rhs[i];
itsString[itsLen] = '\0';
// cout << "\tString(String&)-Konstruktor\n";
// ConstructorCount++;
}

// Destruktor, gibt zugewiesenen Speicher frei
String::~String ()
{
delete [] itsString;
itsLen = 0;
// cout << "\tString-Destruktor\n";
}

// Zuweisungsoperator, gibt vorhandenen Speicher frei,
// kopiert dann String und Groeße
String& String::operator=(const String & rhs)
{
if (this == &rhs)
return *this;
delete [] itsString;
itsLen=rhs.GetLen();
itsString = new char[itsLen+1];
for (int i = 0; i<itsLen;i++)
itsString[i] = rhs[i];
itsString[itsLen] = '\0';
return *this;
// cout << "\tString-Operator=\n";
}

// Nicht konstanter Offset-Operator, gibt Referenz
// auf Zeichen zurueck, das sich damit aendern
// laeßt!
char & String::operator[](int offset)
{
if (offset > itsLen)
return itsString[itsLen-1];
else
return itsString[offset];
}

// Konstanter Offset-Operator fuer konstante
// Objekte (siehe Kopierkonstruktor!)
char String::operator[](int offset) const
{
if (offset > itsLen)
return itsString[itsLen-1];
else
return itsString[offset];
}

// Erzeugt einen neuen String durch Anfuegen von
// rhs an den aktuellen Strings
String String::operator+(const String& rhs)
{
int  totalLen = itsLen + rhs.GetLen();
String temp(totalLen);
int i,j;
for (i = 0; i<itsLen; i++)
temp[i] = itsString[i];
for (j = 0; j<rhs.GetLen(); j++, i++)
temp[i] = rhs[j];
temp[totalLen]='\0';
return temp;
}

// Aendert aktuellen String, gibt nichts zurueck
void String::operator+=(const String& rhs)
{
unsigned short rhsLen = rhs.GetLen();
unsigned short totalLen = itsLen + rhsLen;
String  temp(totalLen);
int i, j;
for (i = 0; i<itsLen; i++)
temp[i] = itsString[i];
for (j = 0; j<rhs.GetLen(); j++, i++)
temp[i] = rhs[i-itsLen];
temp[totalLen]='\0';
*this = temp;
}

// int String::ConstructorCount = 0;


Dieser Post wurde am 06.09.2007 um 10:58 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
06.09.2007, 11:03 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


lass es mal durch ein indent laufen (Strg+A, Strg+K, Strg+F in der Reihenfolge im VS)

dann siehst du warum.

korrektes einrücken kann helfen den Fehler zu finden:


C++:
const char * GetString() const { return itsString; // < missing }


--
class God : public ChuckNorris { };

Dieser Post wurde am 06.09.2007 um 11:04 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
06.09.2007, 11:34 Uhr
ProgramPaula



hmm, haut auch nach Einrücken nicht hin. Sieht sauber aus.

Liegt es vielleicht an einer falschen Compilereinstellung?

C++:
#include <iostream>
//#include <string>

using std::cin ;
using std::cout ;
using std::endl ;

class String
{
public:
    // Konstruktoren
    String();
    String(const char *const);
    String(const String &);
    ~String();

    // ueberladene Operatoren
    char & operator[](int offset);
    char operator[](int offset) const;
    String operator+(const String&);
    void operator+=(const String&);
    String & operator= (const String &);

    // Allgemeine Zugriffsfunktionen
    int GetLen()const { return itsLen; }
    const char * GetString() const { return itsString;
    // static int ConstructorCount;

private:
    String (int);         // Privater Konstruktor
    char * itsString;
    unsigned short itsLen;

    };

    // Standardkonstruktor erzeugt String von 0 Bytes Laenge
    String::String()
    {
        itsString = new char[1];
        itsString[0] = '\0';
        itsLen=0;
        // cout << "\tString-Standardkonstruktor\n";
        // ConstructorCount++;
    }

    // Privater (Hilfs-) Konstruktor, der nur von Methoden
    // der Klasse zum Erzeugen neuer Null-Strings der
    // erforderlichen Groeße verwendet wird.
    String::String(int len)
    {
        itsString = new char[len+1];
        for (i = 0; i<=len; i++)
            itsString[i] = '\0';
        itsLen=len;
        // cout << "\tString(int)-Konstruktor \n";
        // ConstructorCount++;
    }

    //Konvertiert ein Zeichen-Array in einen String
    String::String(const char * const cString)
    {
        itsLen = strlen(cString);
        itsString = new char[itsLen+1];
        for (i = 0; i<itsLen; i++)
            itsString[i] = cString[i];
        itsString[itsLen]='\0';
        // cout << "\tString(char*)-Konstruktor\n";
        // ConstructorCount++;
    }

    // Kopierkonstruktor
    String::String (const String & rhs)
    {
        itsLen=rhs.GetLen();
        itsString = new char[itsLen+1];
        for (int i = 0; i<itsLen;i++)
            itsString[i] = rhs[i];
        itsString[itsLen] = '\0';
        // cout << "\tString(String&)-Konstruktor\n";
        // ConstructorCount++;
    }

    // Destruktor, gibt zugewiesenen Speicher frei
    String::~String ()
    {
        delete [] itsString;
        itsLen = 0;
        // cout << "\tString-Destruktor\n";
    }

    // Zuweisungsoperator, gibt vorhandenen Speicher frei,
    // kopiert dann String und Groeße
    String& String::operator=(const String & rhs)
    {
        if (this == &rhs)
            return *this;
        delete [] itsString;
        itsLen=rhs.GetLen();
        itsString = new char[itsLen+1];
        for (int i = 0; i<itsLen;i++)
            itsString[i] = rhs[i];
        itsString[itsLen] = '\0';
        return *this;
        // cout << "\tString-Operator=\n";
    }

    // Nicht konstanter Offset-Operator, gibt Referenz
    // auf Zeichen zurueck, das sich damit aendern
    // laeßt!
    char & String::operator[](int offset)
    {
        if (offset > itsLen)
            return itsString[itsLen-1];
        else
            return itsString[offset];
    }

    // Konstanter Offset-Operator fuer konstante
    // Objekte (siehe Kopierkonstruktor!)
    char String::operator[](int offset) const
    {
        if (offset > itsLen)
            return itsString[itsLen-1];
        else
            return itsString[offset];
    }

    // Erzeugt einen neuen String durch Anfuegen von
    // rhs an den aktuellen Strings
    String String::operator+(const String& rhs)
    {
        int  totalLen = itsLen + rhs.GetLen();
        String temp(totalLen);
        int i,j;
        for (i = 0; i<itsLen; i++)
            temp[i] = itsString[i];
        for (j = 0; j<rhs.GetLen(); j++, i++)
            temp[i] = rhs[j];
        temp[totalLen]='\0';
        return temp;
    }

    // Aendert aktuellen String, gibt nichts zurueck
    void String::operator+=(const String& rhs)
    {
        unsigned short rhsLen = rhs.GetLen();
        unsigned short totalLen = itsLen + rhsLen;
        String  temp(totalLen);
        int i, j;
        for (i = 0; i<itsLen; i++)
            temp[i] = itsString[i];
        for (j = 0; j<rhs.GetLen(); j++, i++)
            temp[i] = rhs[i-itsLen];
        temp[totalLen]='\0';
        *this = temp;
    }

    // int String::ConstructorCount = 0;



Bearbeitung von 0xdeadbeef:

cpp-tags eingefügt. Nächstes mal selbst machen.


Dieser Post wurde am 06.09.2007 um 14:48 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
06.09.2007, 11:40 Uhr
Blubber2063



Omg Flosoft hat dir die Stelle deines Fehlers doch schon eindeutig benannt.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
06.09.2007, 12:13 Uhr
ProgramPaula



Hallo Blubber und Flosoft,

vielen Dank für die Lösung (Flosoft) und eure Hilfe. War ich tatsächlich zu blöd den Code aus dem Buch zu kopieren.....

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
06.09.2007, 18:35 Uhr
öni



Naja wer nicht hören will tut erst mal einrücken hat doch auch seinen Sinn gehabt....
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
06.09.2007, 19:43 Uhr
xXx
Devil



C++:
namespace my
{
#include <cstring>
    template<typename T>
    class string
    {
    public:
        string() : m_length(0) { m_data = new T[m_length + 1]; m_data[m_length] = 0; }
        string(T const * const str) : m_length(std::strlen(str)) { m_data = new T[m_length + 1];    std::memcpy(m_data, str, m_length * sizeof(T)); m_data[m_length] = 0; }
        string(const string&) : m_length(rhs.length()) { m_data = new T[m_length + 1]; std::memcpy(m_data, rhs.c_str(), m_length * sizeof(T)); m_data[m_length] = 0; }
        ~string() { delete [] m_data;    }

    public:
        T& operator[](std::size_t pos)    { return m_data[pos]; }
        T const& operator[](std::size_t pos) const { return m_data[pos]; }
        string operator+(const string& rhs)
        {
            std::size_t len = m_length + rhs.length();
            T* data = new T[len + 1];
            std::memcpy(&data[0], m_data, m_length * sizeof(T));
            std::memcpy(&data[m_length], rhs.c_str(), rhs.length()* sizeof(T));
            data[len] = 0;
            string tmp(data);
            delete [] data;
            return tmp;
        }

        void operator+=(const string& rhs)
        {
            string tmp(*this);
            m_length += rhs.length();
            delete [] m_data;
            m_data = new T[m_length + 1];
            std::memcpy(&m_data[0], tmp.c_str(), tmp.length() * sizeof(T));
            std::memcpy(&m_data[tmp.length(), rhs.c_str(), rhs.length() * sizeof(T));
            m_data[m_length] = 0;
        }

        string& operator= (const string& rhs)
        {
            if (this == &rhs) return *this;

            delete [] m_data;
            m_length = rhs.length();
            m_data = new T[m_length + 1];
            std::memcpy(m_data, rhs.c_str(), m_length * sizeof(T));
            m_data[m_length] = 0;
            return *this;
        }

    public:
        std::size_t    length() const    {    return m_length;    }
        T const* c_str()() const    {    return m_data;        }
        T const& at(std::size_t pos) const { if (pos >= m_length) throw std::out_of_range("at"); return m_data[pos]; }
        T& at(std::size_t pos) {  if (pos >= m_length) throw std::out_of_range("at"); return m_data[pos]; }

    private:
        T*            m_data;
        std::size_t    m_length;
    };

    typedef string<char>    cstring;
    typedef string<wchar_t>    wstring;
};


C++:
#include "my_string.h"
#include <iostream>

int main()
{
    my::cstring    string("Das ist ja toll!");
    std::cout << string.c_str() << " | " << string.length() << std::endl;
    my::wstring unicode(L"UNICODE 4-ever!");
    std::wcout << unicode.c_str() << L" | " << unicode.length() << std::endl;
}
Ehm deines ein wenig umgeformt ... ob es alles korrekt ist hab ich nicht geprüft ... ein wenig an den Standard angepasst usw... naja ... hab es aber nunmal noch nicht kompiliert ... sorry...

Dieser Post wurde am 06.09.2007 um 19:44 Uhr von xXx editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: