简体   繁体   English

如何在 C++ 的类的默认构造函数中调用成员 object 变量的参数化构造函数?

[英]How to call parameterized constructor of member object variable in a class' default constructor in C++?

I want to initialize member object variables in the default constructor of the class.我想在 class 的默认构造函数中初始化成员 object 变量。

Let's consider the following,让我们考虑以下内容,

class ABC {    
    ABC(int A, int B) {
        a = A;
        b = B;
    }

    int a;
    int b;
};


class Foo {
    Foo();

    ABC m_obj1;
};

From the above example, I would like to initialize "obj1" in "Foo::Foo()".从上面的例子中,我想在“Foo::Foo()”中初始化“obj1”。 One of the restrictions I have is that I cannot do so in the initializer list, as I need to do some computation before I could initialize the member.我的限制之一是我不能在初始化列表中这样做,因为我需要在初始化成员之前进行一些计算。 So the option available (ASFAIK) is to do so in the body of the default constructor only.所以可用的选项(ASFAIK)是只在默认构造函数的主体中这样做。

Any inputs, how could I do this?任何输入,我该怎么做? Edit: Restricting to C++11编辑:限制为 C++11

Would this be a correct way,这会是一个正确的方法,

Foo:Foo() {
    int x = 10;
    int y = 100;

    m_Obj1(x, y);     //Is this correct? <--------
}

Depending on your exact problem and requirements, multiple solutions might be available:根据您的具体问题和要求,可能会提供多种解决方案:


Option 1: Use a function to do the computations and call Foo constructor选项 1:使用 function 进行计算并调用Foo构造函数

Foo makeFoo()
{
    // Computations here that initialize A and B for obj1 constructor
    return Foo(A, B)
}

Option 2: Call a function that does the computations and initialize obj1 in Foo member initializer list选项 2:调用 function 执行计算并在Foo成员初始化程序列表中初始化obj1

ABC initABC() {
    // Some computations
    return ABC(A, B)
}

Foo() : obj1(initABC()) {}

Option 3: Dynamically allocate obj1, for instance with a std::unique_ptr选项 3:动态分配 obj1,例如使用std::unique_ptr


Option 4: Use std::optional or an emulated c++11 version as shown by other answers选项 4:使用std::optional或模拟的 c++11 版本,如其他答案所示

You simply call the base constructor inside the initializer list of the derived constructor.您只需在派生构造函数的初始值设定项列表中调用基本构造函数。 The initializer list starts with ":" after the parameters of the constructor.初始化列表在构造函数参数之后以“:”开头。 See example code!见示例代码!

There is no problem to call functions inside the initializer list itself.在初始化列表本身中调用函数没有问题。

int CallFunc1(int x) { return x*2; }
int CallFunc2(int y) { return y*4; }

class ABC {
    public:
        ABC(int A, int B):a{CallFunc1(A)},b{CallFunc2(B)} {
            std::cout << "Constructor with " << a << " " << b << " called" << std::endl;
        }
    private:

        int a;
        int b;
};




class Foo {
    public:
    Foo(): obj1(1,2){}
    Foo( int a, int b): obj1(a, b){}

    private:
    ABC obj1;
};

int main()
{
    Foo foo;
    Foo fooo( 9,10);
}

edit:编辑:

The best method I can think of for your case is a copy constructor, being more specific on what you need to store helps a lot since if it is just two ints inside a class dynamic allocation is not worth it, the size of the object being constructed makes a difference to what method is best, copy constructors can be slower with much larger data types as the object has to be created twice: once when it is automatically constructed in the parent objects constructor and again when a temporary object is created and all the values have to be copied, which can be slower then dynamically allocating if the size is larger.对于您的情况,我能想到的最佳方法是复制构造函数,更具体地说明您需要存储的内容会很有帮助,因为如果它只是 class 动态分配中的两个整数,那么 object 的大小是构造对哪种方法最好有影响,对于更大的数据类型,复制构造函数可能会更慢,因为 object 必须创建两次:一次是在父对象构造函数中自动构造时,另一次是在创建临时 object 时必须复制这些值,如果大小较大,这可能会比动态分配更慢。

  1. As far as I'm aware all objects in a class are automatically initialized/allocated in the constructor so sadly dynamic memory use may be your best bet here.据我所知,class 中的所有对象都会在构造函数中自动初始化/分配,因此可悲的是动态 memory 使用可能是您最好的选择。

  2. If you are fine with having the object initialized but empty so you know it is not 'ready' yet you can later fill it with useful data when you would have wanted to initialize it.如果您对 object 初始化但为空感到满意,那么您知道它还没有“准备好”,但您可以稍后在您想要初始化它时用有用的数据填充它。 This can be done with default constructors that set the things inside the object to null values or something similar so you know the object hasn't been properly initialized yet.这可以通过将 object 中的内容设置为 null 值或类似值的默认构造函数来完成,因此您知道 object 尚未正确初始化。 Then before using the object you can check whether it has been initialized by checking for the null values or by having put a bool in the object that tells you whether it is initialized.然后在使用 object 之前,您可以通过检查 null 值或通过在 object 中放置一个告诉您它是否已初始化的布尔值来检查它是否已初始化。 Dynamically allocated would still be better in my opinion and makes the code look cleaner overall as all you need to store is a null pointer until the object is needed and then allocated and set to the pointer.在我看来,动态分配仍然会更好,并使代码看起来更干净,因为您需要存储的只是 null 指针,直到需要 object 然后分配并设置为指针。 It is also very easy to check if the pointer is equal to nullptr to know the state of your object.也很容易检查指针是否等于 nullptr 以了解 object 的 state。

Dynamically allocating memory may be a hassle since you have to make sure to get rid of memory leaks and it is slightly slower than using the stack, but it is a necessary skill for c++ since the stack is not enough when making programs that use more than the few available megabytes of data on the stack so if you are doing this simply to avoid the hassle I recommend learning it properly.动态分配 memory 可能很麻烦,因为您必须确保摆脱 memory 泄漏,并且比使用堆栈稍慢,但是对于 Z6CE809EACF90BA125B40FA4BD90396堆栈上可用的几兆字节数据,所以如果你这样做只是为了避免麻烦,我建议正确学习它。 It would be nice if you could be more specific about what kind of object you want to do this with or if you just want an answer that works for most cases.如果您能更具体地了解您想要使用哪种 object 或者您只是想要一个适用于大多数情况的答案,那就太好了。 eg:例如:

*ABC obj1 = nullptr;
...object is needed
obj1 = new(ABC(constructor stuff));
...obj1 isn't needed
delete obj1;

or c++ automatically deletes it when the program closes.或 c++ 在程序关闭时自动删除它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在C++中调用Base class的参数化构造函数? - How to call parameterized Constructor of Base class in C++? C++ 父 Class 调用默认构造函数而不是参数化构造函数 - C++ Parent Class Default Constructor Called Instead of Parameterized Constructor C++ 何时会调用 object 上的构造函数,该 class 成员? - When will C++ call the constructor on an object that is a class member? 将 object 分配给 C++ class 构造函数中的成员变量 - Assign object to a member variable in C++ class constructor 如果我在 C++ 的类构造函数中显式构造它,是否会在类成员变量上调用默认构造函数? - Is a default constructor called on a class member variable if I am explicitly constructing it in the class constructor in c++? 如何在C ++中从单个对象调用参数化和非参数化构造函数 - how to call parameterized and non parameterized constructor from single object in c++ 复制具有C ++中没有默认构造函数的成员的类的构造函数 - Copy constructor for class that has member without default constructor in C++ 具有数组成员变量的C ++类构造函数 - C++ Class Constructor With Array Member Variable How to initialize class member variable char[][] in C++ constructor? - How to initialize class member variable char[][] in C++ constructor? C ++:为拥有类成员的类创建默认构造函数(该成员缺少默认构造函数) - C++:creating default constructor for a class that owns a class member(the member lacks default constructor)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM