调用类数组成员的非默认构造函数
Invoke non-default constructor for class array member
我的类中有一个名为 items
的数组。创建 MyClass
类型的对象时,需要调用参数化构造函数Member(int value)
。怎么做?
class Member
{
public:
Member();
Member(int value)
{
dummy = value * 2;
}
~Member();
private:
int dummy;
}
class MyClass
{
public:
MyClass();
~MyClass();
private:
Member items[10];
}
更新:我现在正在用单个元素而不是数组来消除更简单的情况。也许你看到更多:为什么会这样
user_menu_view::user_menu_view() :
button_clicked_callback(this, &user_menu_view::button_clicked),
on_touch_button_item_selected(this, &user_menu_view::touch_button_item_selected),
users_items(menu_item_common::BACKG_LONG)
{
users_items.set_back_color((uint16_t)0x1951);
users_items.set_menu_item_selected_callback(on_touch_button_item_selected);
meniu_list.add(users_items);
}
这不会:
user_menu_view::user_menu_view() :
button_clicked_callback(this, &user_menu_view::button_clicked),
on_touch_button_item_selected(this, &user_menu_view::touch_button_item_selected)//,
//users_items(menu_item_common::BACKG_LONG)
{
users_items = menu_item_touch_button::menu_item_touch_button(menu_item_common::BACKG_LONG);
// Also, here destructor routine is called. WHy???
users_items.set_back_color((uint16_t)0x1951);
users_items.set_menu_item_selected_callback(on_touch_button_item_selected);
meniu_list.add(users_items);
}
您可以初始化数组:
#include <iostream>
#include <array>
struct Element
{
Element() : _value(0) {}
Element(int value) : _value(value) {}
int _value;
};
class Container
{
std::array<Element, 10> _elements; // Element _elements[10]; works too
public:
Container()
: _elements({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 })
{}
int at(size_t index) { return _elements[index]._value; }
};
int main()
{
Container cont;
std::cout << cont.at(5) << std::endl;
}
按预期打印6
。
数组内容将由默认构造函数 Member
初始化。若要用单个内容填充它,您需要一些额外的代码来替换默认构造的值,通常在数组所属的类的构造函数中。
您还应该考虑使用 std::vector
或 std::list
,无论哪种更适合您的用例,如果可能的话,而不是 C 数组。
class MyClass
{
public:
MyClass() {
for(int i=0;i<10;++i)
items[i]=Member(i);
}
~MyClass();
private:
Member items[10];
}
UPD:您需要仔细实现 Member 类的析构函数和复制构造函数。它必须无效,并且在复制并替换为值时不会使逻辑崩溃。复制构造函数如下所示:
Member( const Member& m ) {
dummy = m.dummy;
}
如果您的编译器支持 C++11,您可以像这样简单:(可能它解决了复制复杂类对象的问题(
class MyClass
{
public:
MyClass() : items({0,1,2,3,4,5,6,7,8,9}) {};
~MyClass();
private:
Member items[10];
};
我想你对在构建对象的过程中究竟会发生什么有点困惑。
class MyClass
{
private:
Member_x x;
Member_y y;
public:
MyClass( int i ) : x( i );
{
y = Member_y( 42 );
}
};
当复制构造函数到达该开{
时,所有未在成员初始值设定项列表中显式构造的成员变量都已默认构造。
这是一个要求,因此所有成员变量都处于明确定义的状态,因此您可以在构造函数主体中实际访问它们。
这意味着在我的示例中调用复制构造函数将:
- 呼叫
Member_x( i )
; - 隐式调用
Member_y()
; - 调用
~Member_y()
(因为y
引用的对象在分配新值时超出范围(; - 呼叫
Member_y( 42 )
。
这显然不是你想要的 - 你想避免隐式构造函数/析构函数调用。执行此操作的唯一方法是将初始化移动到成员初始值设定项列表中。
为什么会这样工作
因为它正在成员初始值设定项列表中调用复制构造函数(与我示例中的Member_x
一样(
这不会:
因为它调用默认构造函数,然后在构造函数主体中分配一个新值(如我示例中的Member_y
(。它也"工作",它只是做额外的和不必要的工作。
因此,如果要初始化成员初始值设定项列表中的Member items[]
- 使用
Member
复制构造函数, - 不希望默认构造/销毁临时
Member
对象。
用户 oklas 的第二个答案是用一个普通的旧数组来做到这一点的,YSC 用 std::array
来做,也可以用 std::vector
做同样的方式。重要的是初始化是在初始值设定项列表中完成的,而不是在MyClass
构造函数主体中完成的。
两种展示的解决方案都尽可能"简单"和"默认"。
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 初始化具有非默认构造函数的std::数组项的更好方法
- 具有默认模板类型的默认构造函数的类型推导
- 如何使用非默认构造函数实例化模板化类
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 声明没有默认构造函数的字段
- 没有默认构造函数作为模板参数的自定义比较器
- C++17 没有默认构造函数的地图放置(私有默认构造函数)
- 使用移动调用对等构造函数unique_ptr默认构造函数
- C++复制构造函数和默认构造函数
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 为什么即使我调用参数化构造函数也会调用默认构造函数?
- 具有非默认构造函数的单例类
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- 在C++中使用默认构造函数初始化对象的不同方法
- 在没有默认构造函数的情况下创建的派生对象
- 强制使用默认构造函数对成员进行未初始化的声明
- 使用默认构造函数初始化对象的不同方法
- 创建类类型的动态分配数组,其中类不得具有默认构造函数