与成员函数

时间:2016-12-10 17:04:41

标签: c++

我正在尝试使用操作重载来更改子类值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;
  };

1 个答案:

答案 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的错误)。