我在自学C++。我试过书中的一个程序,它通常会使用指针数组动态分配两个派生类的几个对象。然而,我正在准备一个不允许我使用指针的作业,所以我做了一个没有指针的替代版本。
它给我的唯一错误是C2259“不能实例化抽象类”,但我很确定我已经覆盖了所有的虚函数。
下面是标题:
#ifndef ACCTBAC_H_ #define ACCTBAC_H_ #include <iostream> #include <string> // Abstract Base Class class AcctABC { private: std::string fullName; long acctNum; double balance; protected: struct Formatting { std::ios_base::fmtflags flag; std::streamsize pr; }; const std::string& FullName() const { return fullName; } long AcctNum() const { return acctNum; } Formatting SetFormat() const; void Restore(Formatting& f) const; public: AcctABC(const std::string& s = "Nullbody", long an = -1, double bal = 0.0); void Deposit(double amt); virtual void Withdraw(double amt) = 0; // pure virtual function double Balance() const { return balance; }; virtual void ViewAcct() const = 0; // pure virtual function virtual ~AcctABC() {} }; // Brass Account Class class Brass : public AcctABC { public: Brass(const std::string& s = "Nullbody", long an = -1, double bal = 0.0) : AcctABC(s, an, bal) {} virtual void Withdraw(double amt); virtual void ViewAcct() const; virtual ~Brass() {} }; // Brass Plus Account Class class BrassPlus : public AcctABC { private: double maxLoan; double rate; double owesBank; public: BrassPlus(const std::string& s = "Nullbody", long an = -1, double bal = 0.0, double ml = 500, double r = 0.10); BrassPlus(const Brass& ba, double ml = 500, double r = 0.1); virtual void ViewAcct() const; virtual void Withdraw(double amt); void ResetMax(double m) { maxLoan = m; } void ResetRate(double r) { rate = r; } void ResetOwes() { owesBank = 0; } }; #endif
类函数:
// acctabc.cpp -- bank account class methods
#include <iostream>
#include "acctabc.h"
using std::cout;
using std::ios_base;
using std::string;
// Abstract Base Class
AcctABC::AcctABC(const string& s, long an, double bal)
{
fullName = s;
acctNum = an;
balance = bal;
}
void AcctABC::Deposit(double amt)
{
if (amt < 0)
cout << "Negative deposit not allowed; "
<< "deposit is cancelled.\n";
else
balance += amt;
}
void AcctABC::Withdraw(double amt)
{
balance -= amt;
}
// protected methods for formatting
AcctABC::Formatting AcctABC::SetFormat() const
{
// set up ###.## format
Formatting f;
f.flag = cout.setf(ios_base::fixed, ios_base::floatfield);
f.pr = cout.precision(2);
return f;
}
void AcctABC::Restore(Formatting& f) const
{
cout.setf(f.flag, ios_base::floatfield);
cout.precision(f.pr);
}
// Brass methods
void Brass::Withdraw(double amt)
{
if (amt < 0)
cout << "Withdrawal amount must be positive; "
<< "withdrawal cancelled.\n";
else if (amt <= Balance())
AcctABC::Withdraw(amt);
else
cout << "Withdrawal amount of $" << amt
<< " exceeds your balance.\n"
<< "Withdrawal cancelled.\n";
}
void Brass::ViewAcct() const
{
Formatting f = SetFormat();
cout << "Brass Client: " << FullName() << "\n";
cout << "Account Number: " << AcctNum() << "\n";
cout << "Balance: $" << Balance() << "\n";
Restore(f);
}
// BrassPlus methods
BrassPlus::BrassPlus(const string& s, long an, double bal, double ml, double r) : AcctABC(s, an, bal)
{
maxLoan = ml;
owesBank = 0.0;
rate = r;
}
void BrassPlus::ViewAcct() const
{
Formatting f = SetFormat();
cout << "BrassPlus Client: " << FullName() << "\n";
cout << "Account Number: " << AcctNum() << "\n";
cout << "Balance: $" << Balance() << "\n";
cout << "Maximum loan: $" << maxLoan << "\n";
cout << "Owed to bank: $" << owesBank << "\n";
cout.precision(3);
cout << "Loan Rate: " << 100 * rate << "%\n";
Restore(f);
}
void BrassPlus::Withdraw(double amt)
{
Formatting f = SetFormat();
double bal = Balance();
if (amt <= bal)
AcctABC::Withdraw(amt);
else if (amt <= bal + maxLoan - owesBank)
{
double advance = amt - bal;
owesBank += advance * (1.0 + rate);
cout << "Bank Advance: $" << advance << "\n";
cout << "Finance charge: $" << advance * rate << "\n";
Deposit(advance);
AcctABC::Withdraw(amt);
}
else
cout << "Credit limit exceeded. Transaction cancelled.\n";
Restore(f);
}
和主程序:
// usebrass3.cpp -- polymorphic example using an abstract base class
#include <iostream>
#include <string>
#include "acctabc.h"
#include <vector>
const int CLIENTS = 4;
int main()
{
using std::cin;
using std::cout;
using std::vector;
using std::string;
vector<AcctABC> accounts(CLIENTS);
string temp;
long tempnum;
double tempbal;
char kind;
for (int i = 0; i < CLIENTS; i++)
{
cout << "Enter client's name: ";
getline(cin, temp);
cout << "Enter client's account number: ";
cin >> tempnum;
cout << "Enter opening balance: $";
cin >> tempbal;
cout << "Enter 1 for Brass Account: ";
while (cin >> kind && (kind != '1' && kind != '2'))
cout << "Enter either 1 or 2: ";
if (kind == 1)
accounts.push_back(Brass(temp, tempnum, tempbal));
else
{
double tmax, trate;
cout << "Enter the overdraft limit: $";
cin >> tmax;
cout << "Enter the interest rate "
<< "as a decimal fraction: ";
cin >> trate;
accounts.push_back(BrassPlus(temp, tempnum, tempbal, tmax, trate));
}
while (cin.get() != '\n')
continue;
}
cout << "\n";
for (int i = 0; i < CLIENTS; i++)
{
accounts[i].ViewAcct();
cout << "\n";
}
cout << "Done.\n";
return 0;
}
你不能这样做
vector<AcctABC> accounts(CLIENTS);
因为它将使
vector<std::unique_ptr<AcctABC>> accounts;
然后例如
accounts.push_back(std::make_unique<Brass>(temp, tempnum, tempbal));
此处:
vector<AcctABC> accounts(CLIENTS);
您正在尝试使用