visual-c++ - 代码适用于其他 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;
}
解决方案
在这种情况下,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++ 没有自动转换或规定来涵盖此类情况。其他编译器应该给出相同的错误,前提是您以足够高的合规级别运行它们。
解决方法是更改 的构造函数Lebensmittel
,Artikel
并Moebel
采用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);
| ^~~~~~~~~~~
推荐阅读
- kotlin - 如何从 Kotlin 内部访问函数?
- python - 使用 beautifulsoup 从 html 中提取数据
- java - 尝试将颜色数据从顶点传递到片段着色器时,Vbos 绘制黑色
- reactjs - 在路由上传递参数后如何转到基本网址?
- javascript - Json-server 错误:数据必须是对象。需要将 JSON 数组更改为 JSON 对象
- r - 如何在 R 中运行具有二元结果的高原二次模型?
- android - BLE 4.0/4.1 在 Android 中支持 64 字节的数据传输
- apache-spark - Databricks - 创建输出文件
- pandas - 熊猫 read_sql_query -> to_string。删除列之间的空格 (FWF)
- c++ - x86 内在函数在 boost::uuids::operator <