如何在另一个类的构造函数中初始化对象?
How can I initialize an object in the constructor of another class?
在我的项目中,我有相互连接的类。 如果一个类有一个另一个类的对象作为属性,我在编写构造函数时如何初始化它?
我试图写如下,但我有一个错误。请注意,类 Date 有一个构造函数,它是 Date()。如果我写 dueDate = 0 ,它会给出一个错误。
同样在任务(字符串 n ,日期 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;
}
假设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)) {}
这会将您的用例更改为只需要接受int
的Date
的构造函数(显式或其他构造函数)(或指针,其中0
将被解释为NULL
指针),而不需要处理从0
到现有实例的赋值。
这样做也更有效;而不是五个默认构造和五个重新分配,你只需从一开始就使用预期的参数进行五个直接构造。在构造函数接受string
和Date
的情况下,使用std::move
意味着对象只从头开始构造一次(当调用者调用构造函数时),然后 move-construction 用于挖空参数并将其内部移动到数据成员,而不是复制构造只是为了丢弃源代码。
如果必须分配给现有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
重新分配给一个新的空Date
,而它已经是一个空Date
。
你有几个选择。
首先,创建一个指针:
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);
}
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;
}
- C++使用整数的压缩数组初始化对象
- 如何使用cudaMallocManaged在指针位置初始化对象?(C++)
- 在 c++ 中初始化对象
- C++ 手动分配和初始化对象
- 使用运算符"="在C++中用值初始化对象
- 当我不需要数据库中的所有值时,如何部分初始化 c++ 对象?
- 如何初始化对象数组?
- 在C++中使用默认构造函数初始化对象的不同方法
- 使用默认构造函数初始化对象的不同方法
- 是否可以在编译时初始化对象的 C 样式函数指针,以便它调用对象的成员函数?
- 如何在线程中初始化对象,然后在其他地方使用它?
- 在没有默认构造函数时使用垃圾数据初始化对象
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 初始化对象以在 C++08 中作为参数传递的首选语法是什么?
- 在 c++ 中复制对未初始化对象的引用
- 在成员变量在另一个文件中发生更改后,调用与初始化对象分开的函数
- 在不放置新运算符的情况下,在预分配的内存上使用虚函数初始化对象 - 这可能吗?如果没有,为什么
- 复制 CTOR 与赋值运算符以初始化对象(性能)
- 当您通过分配初始化C 对象时会发生什么
- 获取未初始化对象成员的地址是否定义良好?