3

我正在为一项任务制作一组派生类。我被指示使用 char 数组(c 字符串)。当我编译时,我不断收到错误:

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;
}
4

2 回答 2

10

正确的语法是Business bs1(1,businessName1);. 如果要使用=,还可以使用复制初始化Business bs2 = Business(2,businessName2);

前者称为直接初始化。但是它们并不完全相同,请参阅复制初始化和直接初始化之间的 C++ 有区别吗?以获得更深入的信息。

在and 数组中用逗号Business bs1 = (1,businessName1);分隔。逗号运算符评估第一个操作数,即丢弃结果并返回第二个操作数的值,在您的情况下这是一个数组。换句话说,您的代码相当于. 这就是错误消息说它无法将 a 转换为对象的原因。1businessName11Business bs1 = businessName1;char[10]Business

于 2013-04-23T21:37:14.460 回答
1

将产生错误的第一行更改为Business bs1(1,businessName1);和其余类似。这是在堆栈上初始化类实例的 C++ 习惯用法。

Business bs2 = Business(2,businessName2);正如 Jesse Good 所建议的那样,我认为这是一个 Java 习语,在 C++ 中的实践很差。它比较慢,因为有两个隐式构造函数调用和一个复制构造函数调用,而不是Business bs1(1,businessName1);. 在这种情况下还有另一个陷阱:您没有为该Business类型定义复制构造函数,这意味着编译器将为您创建一个执行浅拷贝的构造函数。 bs2.name最终会得到一个指向内存的指针,当bs2超出范围时不一定正确释放 - 典型的内存泄漏。

相应的 C++ 习惯用法是在堆上构造一个新对象,然后将其地址分配给一个指针:Business *bs2 = new Business(2,businessName2);

您的代码还有另一个问题。通常,在 C 或 C++ 中按名称分配数组也是一种不好的风格(请记住,静态分配的字符串char theName[]只是一种特殊的数组)。查看getName()in的定义Person

void getName(char theName[])
    { theName = name; }

这是分配数组名称(不完全是指针,而是近亲),而不是将一个字符串的内容复制到另一个字符串。然后在printBal()你写

char name[80];
getName(name);

执行时它将局部变量getName()绑定到参数。到目前为止,一切都很好,尽管您选择的变量名称可能不会那么混乱。:) 但是随后执行主体并将私有实例变量的地址分配给(这是一个数组的名称——同样,一种特殊的指针)。返回时,不会对. 正确的编写方法是 with ,即您编写第二个构造函数的方式:printBal()nametheNamegetName()nametheNamegetName()nameprintBal()Person::getName()strcpy()Person

void getName(char theName[])
    { strcpy(theName,name); }
于 2013-04-23T21:54:54.953 回答