首页 > 解决方案 > 如何在另一个类的构造函数中初始化对象?

问题描述

在我的项目中,我有相互连接的类。如果一个类具有另一个类的对象作为属性,我在编写构造函数时如何初始化它?

我试着写如下,但我有一个错误。请注意,Date 类有一个构造函数,即 Date()。如果我写 dueDate = 0 ,它会给出一个错误。

同样在 Task(string n , Date d) 中,我可以初始化其他属性还是只初始化参数?

class Task
{
   private:
   int id;
   string name;
   Date dueDate;
   string status;
   bool urgent;

   public:
   Task();
   Task(string n, Date d);
};

Task::Task(){
   id = 0;
   name = "*";
   dueDate = 0;
   status = "New";
   urgent = false;
}
Task::Task(string n, Date d){
   name = n;
   dueDate = d;
}

标签: c++

解决方案


假设Date为 提供了一个构造函数int,正确的解决方案是切换到成员初始化器列表,而不是在构造函数的主体中分配(这意味着所有成员都默认初始化,然后重新分配)。只需将所有作业移至初始化,如下所示:

Task::Task() : id(0), name("*"), dueDate(0), status("New"), urgent(false) {}
Task::Task(string n, Date d) : name(std::move(n)), dueDate(std::move(d)) {}

这会将您的用例更改为只需要一个构造函数(显式或其他)来Date接受int(或指针,其中0将被解释为NULL指针),而不是需要处理0对现有实例的赋值。

这样做也更有效率;而不是五个默认构造和五个重新分配,您只需从一开始就使用预期的参数进行五个直接构造。在构造函数接受stringand的情况下Date, usingstd::move意味着对象只从头开始构造一次(当调用者调用构造函数时),然后使用 move-construction 掏空参数并将它们的内部移动到数据成员而不是复制构建只是为了扔掉源代码。

如果您必须分配给现有的Date并且它不能int为您隐式转换,如果您有移动或复制分配运算符 for Date,则可以重用它。在这种情况下,对您的代码的最小修复就是替换:

dueDate = 0;

和:

dueDate = Date(0);  // Explicitly construct a `Date` then copy/move assign to dueDate

但同样,使用初始化列表是这里的方法。

注意: IfDate的唯一构造函数不带参数,如您的示例所示:

Date::Date()
{
   day = 0;
   month = 0;
}

如果您只希望它具有默认值,则不需要显式初始化或分配它。在执行包含它们的类的构造函数主体之前,数据成员会自动使用其默认构造函数进行初始化;Date()自动发生。在这种情况下将更加没有意义,因为当它已经一个 empty时dueDate = Date();,它只会重新分配dueDate给一个新的 empty 。DateDate


推荐阅读