为类数组成员调用非默认构造函数

时间:2016-02-15 10:01:57

标签: c++ constructor

我的班级中有一个名为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);
}

5 个答案:

答案 0 :(得分:2)

您可以初始化数组:

#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

答案 1 :(得分:0)

class MyClass
{
public:
    MyClass() {
        for(int i=0;i<10;++i)
            items[i]=Member(i);
    }
    ~MyClass();

private:
    Member items[10];
}

UPD:你需要仔细实现你的Member类的析构函数和copy-constructor。它必须无效,并且在按值复制和替换时不会导致逻辑崩溃。复制构造函数是这样的:

Member( const Member& m ) {
 dummy = m.dummy;
}

答案 2 :(得分:0)

数组内容将由Member的默认构造函数初始化。要用单个内容填充它,您需要一些额外的代码来替换默认构造的值,通常在数组所属的类的构造函数中。

您应该考虑使用std::vectorstd::list,无论哪种情况更适合您的用例,如果可能,请考虑使用C数组。

答案 3 :(得分:0)

如果您的编译器支持C ++ 11,您可以这样简单地执行: (可能它解决了复制复杂类的对象的问题)

class MyClass
{
public:
    MyClass() : items({0,1,2,3,4,5,6,7,8,9}) {};
    ~MyClass();

private:
    Member items[10];
};

答案 4 :(得分:0)

我认为你对构造一个物体时恰好发生的事情感到有些困惑。

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一样)。它&#34;工作&#34;此外,它只是做了额外的和不必要的工作。

因此,如果您想

必须初始化会员初始化列表中的Member items[]
  1. 使用Member复制构造函数
  2. 不希望默认构建/销毁临时Member个对象。
  3. 用户oklas的第二个答案是使用普通的旧数组,YSC使用std::array执行此操作,并且可以使用std::vector以相同的方式完成。重要的是初始化是在初始化列表中完成的,而不是MyClass构造函数体。

    两种展示的解决方案都是简单的&#34;和&#34;默认&#34;因为它得到了。