код работает для другого ide, но не в Visual Studio 2019 - PullRequest
0 голосов
/ 04 августа 2020

Microsofts VS 2019, похоже, не распознает мой конструктор для "Lebensmittel", в то время как все другие идеи распознают, черт возьми, даже онлайн-идеи не имеют с этим проблем. Есть ли способ выключить это или заставить VS запустить его?

То, что вы видите здесь, является решением для упражнения по кодированию, которое я выполняю прямо сейчас. Как видите, некоторые переменные написаны на немецком языке, приношу свои извинения. Программа - это упражнение по наследству. Подклассы «Lebensmittel» (еда) и «Möbel» (мебель) произошли от класса «Artikel» (товары). У еды есть срок годности (haltbarkeit), который также указан в конструкторе (int haltb), но по какой-то досадной причине VS2019 не распознает параметр int в списке параметров моего конструктора и отказывается запускать код.

#include <iostream>                 // Praeprozessoranweisung

using namespace std;

// Klassendefinition:
class Artikel
{
    // Attribute der Basisklasse muessen als "protected" deklariert werden, damit die abgeleiteten Klassen damit arbeiten koennen
    protected:
        char bezeichnung[20];
        int menge;
        double preis;

    public:
        Artikel(char* bez, double p);
        void einkaufen(int anzahl);
        void verkaufen(int anzahl);
};

// Neue Klassendefinitionen
class Lebensmittel:public Artikel
{
    private:
        int haltbarkeit;
    
    public:
        Lebensmittel(int hatb, char* bez, double p);
        void preis_neu();
};

class Moebel:public Artikel
{
    public:
        Moebel(char* bez, double p);
        void preis_neu();
};



// H A U P T F U N K T I O N
int main()
{
    // Ein Objekt fuer einen Artikel instanziieren
    Lebensmittel bananen(2, "Bananen", 0.75);
    
    // Bananen kaufen
    bananen.einkaufen(2500);
    
    // Bananen verkaufen
    bananen.preis_neu();
    bananen.verkaufen(175);
    
    
    // Ein Objekt fuer einen weiteren Artikel instanziieren
    Moebel schraenke("Schraenke", 250.0);
    
    // Schraenke einkaufen
    schraenke.einkaufen(150);
    
    // Schraenke verkaufen
    schraenke.preis_neu();
    schraenke.verkaufen(25);
    
    return 0;
}


// M E T H O D E N D E F I N I T I O N E N
// Konstruktor
Artikel::Artikel(char* bez, double p)
{
    // Speicherueberlauf vermeiden: Letztes Element auf "Stringende" setzen:
    bezeichnung[19] = '\0';
    // Nur Elemente 1 bis 19 uebertragen:
    for (int i = 0; i < 19; i++)
    {
        bezeichnung[i] = bez[i];
    }
    
    preis = p;
    
    menge = 0;
}

void Artikel::einkaufen(int anzahl)
{
    menge += anzahl;
    double kosten = preis * anzahl;
    // Ausgabe
    cout << endl;
    cout << "Der Einkauf von " << anzahl << " " << bezeichnung << " kostet Sie " << kosten << " Euro." << endl;
    cout << "(Einzelpreis: " << preis << " Euro.)" << endl;
    cout << "Sie haben jetzt " << menge << " " << bezeichnung << "." << endl;
}

void Artikel::verkaufen(int anzahl)
{
    // Vermeiden, dass mehr verkauft wird, als vorhanden ist
    if (anzahl > menge) anzahl = menge;
    menge -= anzahl;
    double kosten = preis * anzahl;
    // Ausgabe
    cout << endl;
    cout << "Der Verkauf von " << anzahl << " " << bezeichnung << " bringt Ihnen " << kosten << " Euro." << endl;
    cout << "(Einzelpreis: " << preis << " Euro.)" << endl;
    cout << "Sie haben jetzt " << menge << " " << bezeichnung << "." << endl;
}


// Neue Methoden fuer abgeleitete Klassen
// Konstruktoren
Lebensmittel::Lebensmittel(int haltb, char* bez, double p):Artikel(bez, p)
{
    haltbarkeit = haltb;
}

Moebel::Moebel(char*bez, double p):Artikel(bez, p)
{}

void Lebensmittel::preis_neu()
{
    if (haltbarkeit < 3) preis = 0.5 * preis;
}

void Moebel::preis_neu()
{
    if (menge > 130) preis = 0.75 * preis;
}

1 Ответ

1 голос
/ 05 августа 2020

Компилятор MSV C довольно точно описывает c в этом случае, в чем проблема.

error C2664: 'Lebensmittel::Lebensmittel(Lebensmittel &&)': cannot convert argument 2 from 'const char [8]' to 'char *'
message : Conversion from string literal loses const qualifier (see /Zc:strictStrings)
message : see declaration of 'Lebensmittel::Lebensmittel'
error C2664: 'Moebel::Moebel(Moebel &&)': cannot convert argument 1 from 'const char [10]' to 'char *'
message : Conversion from string literal loses const qualifier (see /Zc:strictStrings)
message : see declaration of 'Moebel::Moebel'

Код передает const char * функции, объявленной как неконстантные char *. Это недопустимо, и в C ++ нет автоматического c преобразования или обеспечения для таких случаев. Другие компиляторы должны выдавать ту же ошибку, если вы запускаете их на достаточно высоком уровне соответствия.

Исправление состоит в том, чтобы изменить конструкторы Lebensmittel, Artikel и Moebel, чтобы они принимали const char * аргумент вместо char *. Это будет работать из коробки, поскольку ни один из этих конструкторов не пытается фактически изменить указанный буфер символов.


[ EDIT ] Для сравнения: g cc 10.2 на godbolt.org дает следующие ошибки в исходном коде.

<source>: In function 'int main()':
<source>:44:29: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   44 |     Lebensmittel bananen(2, "Bananen", 0.75);
      |                             ^~~~~~~~~
<source>:55:22: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   55 |     Moebel schraenke("Schraenke", 250.0);
      |                      ^~~~~~~~~~~
...