[英]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
。
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;
}
数组内容将由Member
的默认构造函数初始化。 要用单个内容填充它,您将需要一些其他代码来替换默认构造的值,通常是在数组所属的类的构造函数中。
您还应该考虑使用std::vector
或std::list
,如果更适合您的用例,则尽可能使用C数组。
如果您的编译器支持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_y
)。 它也“起作用”,它只是做其他不必要的工作。
所以,你必须初始化你的Member items[]
在成员初始化列表,如果你想
Member
副本构造函数, Member
对象默认构造/销毁。 oklas用户的第二个答案是使用普通的旧数组执行此操作,YSC使用std::array
完成此操作,也可以使用std::vector
进行相同的操作。 重要的是初始化是在初始化列表中完成的,而不是在MyClass
构造函数主体中完成的。
展示的两种解决方案都具有“简单”和“默认”的功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.