如何在另一个类的构造函数中初始化对象?

时间:2019-04-03 00:44:21

标签: c++

在我的项目中,我有彼此关联的类。如果一个类具有另一个类的对象作为属性,那么在编写构造函数时如何进行初始化?

我尝试如下编写,但出现错误。请注意,类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;
}

3 个答案:

答案 0 :(得分:3)

假设Dateint提供了一个构造函数,那么这里的正确解决方案是切换到member initializer lists而不是在构造函数的主体中 assigning 表示成员均已默认初始化,然后重新分配)。只需将所有分配移至初始化,如下所示:

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将被解释为{{1 }}指针),而不需要处理从NULL到现有实例的分配。

以这种方式进行操作还更加高效;而不是五种默认构造和五种重新分配,您只需使用一开始的预期参数进行五种直接构造。在构造函数接受0string的情况下,使用Date意味着对象仅从头开始构造一次(当调用者调用构造函数时),然后使用move-construction掏空参数并将其内部移动到数据成员,而不是复制构造只是为了扔掉源。

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

Date

具有:

dueDate = 0;

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

注意:如果dueDate = Date(0); // Explicitly construct a `Date` then copy/move assign to dueDate 的唯一构造函数不带参数,如您的示例:

Date

如果只希望它具有默认值,则无需显式初始化或分配它。在执行包含数据成员的类的构造函数主体之前,将使用其默认构造函数自动初始化数据成员。 Date::Date() { day = 0; month = 0; } 自动发生。在这种情况下,Date()会变得毫无意义,因为当它已经为空时,它将dueDate = Date();重新分配给一个新的空dueDate }。

答案 1 :(得分:0)

您有两种选择。

首先,创建一个指针:

class Task
{
   private:
   Date* dueDate;

   //...
};

Task::Task(){
   // ...
   dueDate = new Date(0);
}
Task::~Task(){
   // This way requires a destructor though
   delete dueDate;
}

选项2:您可以重载赋值运算符:

class Date
{
   public:
   void operator=(int i);
};

Date::operator=(int i) {
   // implement construction
}

然后,在任务中:

Task::Task(){
   // ...
   dueDate = 0;
}

这是我所知道的两个选项。在C ++中,无法将构造函数直接作为成员变量来调用。您必须将其用作指针或实现赋值运算符。

编辑:向Shadow Ranger大喊大叫,他在评论中指出C ++ 14及更高版本具有不需要析构函数的解决方案:

class Task
{
   private:
   std::unique_ptr<Date> dueDate;

   //...
};

Task::Task(){
   // ...
   dueDate = std::make_unique<Date>(0);
}

答案 2 :(得分:-2)

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 = new Date(0);
   status = "New";
   urgent = false;
}
Task::Task(string n, Date d){
   name = n;
   dueDate = &d;
}