我正在尝试使用操作重载来更改子类值Capacity,RentRate和RentMin。我对c ++很新,来自java。 我想创建对象
VanIn Van7("Large", 200, 2.0);
ManVanIn ManVan8("Abc", 99999, "Medium", 100, 1.0);
ManVan8 = Van7;
使ManVan8值从“Medium,100,1.0”变为“Large,200,2.0”但我在操作重载方法中不断收到对象限定符错误
using namespace std;
class AbstractVan {
private:
int RentMin;
string Drivername;
long DLno;
string Capacity;
float RentRate;
public:
AbstractVan(string Drivername, long DLno, string Capacity, int RentMin, float RentRate) : Capacity(Capacity), RentMin(RentMin), RentRate(RentRate), DLno(DLno), Drivername(Drivername) {}
void setCapacity(string cap) { Capacity = cap; }
void setRentRate(float rate) {RentRate = rate;}
void setRentMin(int min) {RentMin = min;}
string getCapacity() { return Capacity; }
float getRentRate() { return RentRate; }
int getRentMin() { return RentMin; }
virtual void print() = 0;
};
来自AbstractVan的派生类
class VanIn : public AbstractVan {
public:
VanIn(string Capacity, int RentMin, float RentRate) : AbstractVan(Capacity, RentMin, RentRate) {}
AbstractVan(string Drivername, long DLno, string Capacity, int RentMin, float RentRate) : Capacity(Capacity), RentMin(RentMin), RentRate(RentRate), DLno(DLno), Drivername(Drivername) {}
来自VanIn的派生类
class ManVanIn : public VanIn {
private:
string Drivername;
int DLno;
public:
ManVanIn(string Drivername, long DLno, string Capacity, int RentMin, float RentRate) : VanIn(Drivername, DLno, Capacity, RentMin, RentRate){}
void print() { cout << "Drivername " << this->Drivername << " Registration " << this->DLno << " - " << getCapacity() << endl; }
~ManVanIn() {cout << "Destroy ManVanIn" << endl;}
void operator = (const VanIn &D) {
setCapacity(D.getCapacity());
setRentRate(D.getRentRate());
setRentMin(D.getRentMin());
}
};
条目
int main()
{
VanIn Van7("Large", 200, 2.0);
ManVanIn ManVan8("Abc", 99999, "Medium", 100,1.0);
ManVan8 = Van7;
ManVan8.print();
system("pause");
return 0;
};
答案 0 :(得分:1)
首先,正如您将在后面看到的那样,使用const限定符定义getter是一个好习惯。否则它不能在const对象上调用 - 我稍后会进入。
string getCapacity() const { return Capacity; }
float getRentRate() const { return RentRate; }
int getRentMin() const { return RentMin; }
通过使用const限定符,您声明这些方法只读取对象,并且它们不会更改对象中的任何内容。遵循这个规则&#39; print()也应该用const限定符声明:
virtual void print() const = 0;
第二件事是如果你有至少一个虚方法,析构函数也应该是虚拟的。
virtual ~AbstractVan() = default;
下一个问题出在你的VanIn课程中。构造函数的定义是错误的。 VanIn是AbstractVan的派生类,因此在创建VanIn之前,必须创建基类(在本例中为AbstractVan)。由于AbstractVan没有默认构造函数,因此必须在初始化部分中调用参数(可接受5个参数)。像这样:
VanIn(string Capacity, int RentMin, float RentRate)
: AbstractVan(/* 5 parameters MUST be here */) { }
不要忘记AbstractVan构造函数中的参数顺序(例如,如果它需要字符串,它就不会接受浮动)。
注意:你可能想要使用const string&amp;在此构造函数中而不是字符串。 const string&amp;意味着它是只读参考(没有不必要的复制)。
下一期是在ManVanIn类中。我没有看到使用私有变量。在调用构造函数后,AbstractVan中将保存相同的内容。此外,当您调用ManVanIn的构造函数时,您尝试使用无效数量的参数调用VanIn构造函数。你声明的版本需要3,你给5。
下一个不是问题,但是一个好习惯。当您覆盖虚函数时,请使用覆盖说明符,如下所示:
void print() const override { /* ... */ }
这是一个很好的做法,因为如果你试图覆盖非虚拟的函数,你的程序就不会编译(你可以通过使用它来避免很多错误)。例如,如果您像我一样在Abstract中声明了print函数,并尝试覆盖这样的函数:
double print() override { /* ... */ }
甚至喜欢这个
void print() override { /* ... */ }
编译器会警告您,您正在覆盖非虚拟的函数。在第一种情况下应该很清楚,你没有声明print()成员函数返回double。在第二种情况下,这是因为缺少const限定符。
吸气剂应该是const的原因在于:
void operator = (const VanIn &D) {
setCapacity(D.getCapacity());
setRentRate(D.getRentRate());
setRentMin(D.getRentMin());
}
您的operator = overload接受一个参数,该参数是对VanIn对象的const引用。你在这里说的是你不会在这个函数体内改变VanIn对象。因此编译器不能在const对象上调用非const方法。如果你在这些情况下错过const限定符,你的程序甚至不会编译(它应该给出关于丢弃cv-qualifier的错误)。