首页 > 解决方案 > 代码适用于其他 ide,但不适用于 Visual Studio 2019

问题描述

Microsoft VS 2019 似乎无法识别我的“Lebensmittel”构造函数,而所有其他 ide 都可以,即使在线 ide 也没有问题。有没有办法关闭它或强制 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;
}

标签: visual-c++constructorvisual-studio-2019

解决方案


在这种情况下,MSVC 编译器非常具体地说明了问题所在。

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'

代码将 a 传递const char *给声明为采用non-const 的函数 char *。这是不允许的,并且 C++ 没有自动转换或规定来涵盖此类情况。其他编译器应该给出相同的错误,前提是您以足够高的合规级别运行它们。

解决方法是更改​​ 的构造函数LebensmittelArtikelMoebel采用const char *参数而不是char *. 这将开箱即用,因为这些构造函数都没有尝试实际修改指向的 char 缓冲区。


[编辑] 作为比较, godbolt.org上的gcc 10.2 在原始代码中给出了以下错误。

<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);
      |                      ^~~~~~~~~~~

推荐阅读