我正在为一个赋值创建一组派生类。我被指示使用char数组(c-strings)。当我编译时,我不断收到错误:
Homework11.cpp: In function âint main()â:
Homework11.cpp:72: error: conversion from âchar [10]â to non-scalar type âBusinessâ requested
Homework11.cpp:73: error: conversion from âchar [10]â to non-scalar type âBusinessâ requested
Homework11.cpp:74: error: conversion from âchar [10]â to non-scalar type âAccountâ requested
Homework11.cpp:75: error: conversion from âchar [10]â to non-scalar type âAccountâ requested
我很确定我的问题源于我尝试将实例变量Name设置为发送的参数。这是我的代码,其中包含注释,我相信问题可能存在。
#include <iomanip>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
class Person{
public:
Person() {}
Person(char theName[]) {strcpy(name,theName);}
void getName(char theName[]) // I think the problem may be here or in the line above
{ theName = name;}
private:
char name[80];
};
class Account : public Person{
public:
Account() :accountNum(0),balance(0) {}
Account(int actNo, char theName[])
:Person(theName),accountNum(actNo),balance(0) {}
void setBal(float theBalance)
{balance = theBalance;}
void deposit(float numDeposited)
{ balance = balance + numDeposited;}
float withdraw(float numWithdrawn)
{ balance = balance -numWithdrawn;
return numWithdrawn;}
float getBal() {return balance;}
void printBal();
private:
int accountNum;
float balance;
};
class Business : public Account{
public:
Business() : checkFee(0.0) {}
Business(int actNo, char theName[])
: Account(actNo, theName),checkFee(0.0) {}
float withdraw(float numWithdrawn)
{float newBalance = getBal()-numWithdrawn-checkFee;
setBal(newBalance);
return numWithdrawn;}
void setFee(float fee) {checkFee = fee;}
private:
float checkFee;
};
void Account::printBal()
{
char name[80];
getName(name);
cout<<setw(10)<<"Account # "<<accountNum<<setw(10)<<
name<<setw(10)<<balance<<endl;
}
int main()
{
char businessName1[10]="Business1";
char businessName2[10] ="Business2";
char regularName1[10] = "Regular1";
char regularName2[10] = "Regular2";
//The following 4 lines are the ones I am getting the error for
Business bs1 = (1,businessName1);
Business bs2 = (2,businessName2);
Account rg1 = (1, regularName1);
Account rg2 = (2, regularName2);
cout<<"Intially: "<<endl;
rg1.printBal();
rg2.printBal();
bs1.printBal();
bs2.printBal();
bs1.deposit(1000.00);
bs2.deposit(1000.00);
rg1.deposit(1000.00);
rg2.deposit(1000.00);
cout<<"----------------------------------------"<<endl;
cout<<"After adding 1000.00 to all accounts:"<<endl;
rg1.printBal();
rg2.printBal();
bs1.printBal();
bs2.printBal();
bs1.setFee(1.00);
bs1.withdraw(500);
bs2.withdraw(500);
bs1.deposit(250);
bs2.deposit(250);
rg1.withdraw(500);
rg2.deposit(500);
cout<<"---------------------------------------"<<endl;
cout<<"Finially:"<<endl;
rg1.printBal();
rg2.printBal();
bs1.printBal();
bs2.printBal();
return 0;
}
答案 0 :(得分:7)
正确的语法是Business bs1(1,businessName1);
。如果您想使用=
,还可以使用复制初始化Business bs2 = Business(2,businessName2);
。
前者称为直接初始化。但它们并不完全相同,请参阅Is there a difference in C++ between copy initialization and direct initialization?以获取更深入的信息。
在Business bs1 = (1,businessName1);
中,1
和数组businessName1
由comma operator分隔。逗号运算符计算第一个操作数,即1
并抛弃结果并返回第二个操作数的值,这是您的情况下的数组。换句话说,您的代码相当于Business bs1 = businessName1;
。这就是错误消息说它无法将char[10]
转换为Business
对象的原因。
答案 1 :(得分:0)
将产生错误的第一行更改为Business bs1(1,businessName1);
,其余类似。这是在堆栈上初始化类实例的C ++习惯用法。
Business bs2 = Business(2,businessName2);
是一种Java习惯用法,它在C ++中很难实践。它较慢,因为有两个隐式构造函数调用和一个复制构造函数调用,而不是Business bs1(1,businessName1);
中的单个构造函数调用。在这种情况下,还有另一个陷阱:您尚未为Business
类型定义复制构造函数,这意味着编译器将为您创建一个执行浅复制的复制构造函数。 bs2.name
将结束指向内存的指针,当bs2
超出范围时,该指针不一定正确释放 - 经典的内存泄漏。
相应的C ++习惯用法是在堆上构造一个新对象,然后将其地址分配给指针:Business *bs2 = new Business(2,businessName2);
。
您的代码还有另一个问题。通常,在C或C ++中按名称分配数组也是不好的风格(请记住,静态分配的字符串如char theName[]
只是一种特殊的数组)。查看getName()
中Person
的定义:
void getName(char theName[])
{ theName = name; }
这是分配数组名称(不是指针,但是关闭表兄弟),而不是将一个字符串的内容复制到另一个字符串。然后在printBal()
中写下
char name[80];
getName(name);
执行getName()
时,会将printBal()
的本地变量name
绑定到参数theName
。到目前为止,这么好,虽然你选择的变量名称可能会有点混乱。 :)但是getName()
的主体执行并将私有实例变量name
的地址分配给theName
(这是一个数组的名称 - 再次,一种特殊的指针)。当getName()
返回时,name
中的局部变量printBal()
没有永久更改。写Person::getName()
的正确方法是使用strcpy()
编写第二个Person
构造函数的方式:
void getName(char theName[])
{ strcpy(theName,name); }