C ++在类构造函数中定义常量成员变量 [英] C++ defining a constant member variable inside class constructor

查看:170
本文介绍了C ++在类构造函数中定义常量成员变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,当您的班级中有一个不变的私有成员变量时,它只有一个吸气剂而没有一个setter,它看起来像这样:

Usually when you have a constant private member variable in your class, which only has a getter but no setter, it would look something like this:

// Example.h
class Example {
    public:
        Example(const int value);
        const int getValue() const;
    private:
        const int m_value;
};


// Example.cpp
#include "Example.h"

Example::Example(const int value)
: m_value(value)
{
}

const int Example::getValue() const
{
    return m_value;
}

现在我要执行的操作是拥有一个不变的int成员变量这样,但不必像这样在初始化部分中定义它::m_value(value)我需要一个其他对象-在此示例中,我将使用一个矢量-作为构造函数的参数,并根据参数对象设置m_value。在这种情况下,如果大小大于0,我将尝试设置向量的大小+1。这就是我所做的:

Now what I'm trying to do, is have a constant int member variable like that, but instead of defining it in the initializing section like so: : m_value(value) I need to take an other object - I'll use a vector in this example - as the constructor's parameter, and set m_value based on the parameter object. In this case, I'll try to do vector's size + 1, if the size is above 0. So this is what I did:

Example::Example(std::vector<Example*> myVec)
{
    if (myVec.size()) {
        m_value = myVec.size() + 1;
    }
    else {
        m_value = -1;
    }
}

但是我得到一个错误未初始化的成员'Example :: m_value'具有'const'类型'const int',如果我在初始化部分中初始化m_value,则会收到错误分配只读数据的错误-member'Example :: m_value'这对我来说都是有意义的,我应该得到这些错误,但是我该如何解决呢?

But I get an error uninitialized member 'Example::m_value' with 'const' type 'const int' and if I init m_value inside the initializing section, I get the error assignment of read-only data-member 'Example::m_value' which all makes sense to me, I'm supposed to get those errors, but how could I go around them?

编辑:我只能编辑 m_value 的方法是在对象本身内部(因为m_value是私有的)。只有getter会限制我将m_value设置为除构造函数中设置的值之外的任何值。将常量int用作成员变量是否对我有好处?

Only way I could edit m_value is inside the object itself (since m_value is private). Having only getter would limit me from setting m_value to anything other than what it's set in the constructor. Do I benefit anything from having constant int as a member variable?

推荐答案

使用静态成员函数计算得出所需的结果,并在初始化列表中调用该函数。像这样:

Use a static member function the compute to result you need and call that function in the initialization list. Like this:

// Example.h
class Example {
    public:
        Example(const int value);
        Example(std::vector<Example*> myVec);

        const int getValue() const;
    private:
        const int m_value;

        static int compute_m_value(::std::vector<Example*> &myVec);
};

// Example.cpp
#include "Example.h"

Example::Example(const int value)
: m_value(value)
{
}

Example::Example(std::vector<Example*> myVec)
: m_value(compute_m_value(myVec))
{
}

const int Example::getValue() const
{
    return m_value;
}

int Example::compute_m_value(::std::vector<Example*> &myVec)
{
    if (myVec.size()) {
        return myVec.size() + 1;
    }
    else {
        return -1;
    }
}

在这种特殊情况下,功能非常简单您可以简单地使用三元运算符(aka :m_value(myVec.size()> 0?int(myVec.size()+ 1):int(-1) )在构造函数中直接在初始化时计算值。这就像一个例子,所以即使您需要的答案计算方法可能非常复杂,我也为您提供了一种非常通用的解决问题的方法。

In this particular case, the function is so very simple you can simply use the ternary operator (aka : m_value(myVec.size() > 0 ? int(myVec.size() + 1) : int(-1)) in the constructor to directly compute the value at initialization. This looked like an example, so I gave you a very general method of solving the problem, even when the method of computing the answer you need might be very complex.

普遍的问题是,常量成员变量(以及也是BTW引用的成员变量)必须在初始值设定项列表中进行初始化。但是初始值设定项可以是表达式,这意味着他们可以调用函数。由于此初始化代码是特定于类的,因此它应该是该类私有的(或可能是受保护的)函数。但是,由于在构造类之前调用​​了它来创建值,因此可以t取决于类实例的存在,因此没有 this p ointer。这意味着它必须是一个静态成员函数。

The general issue is that constant member variables (and member variables that are references too BTW) must be initialized in the initializer list. But initializers can be expressions, which means they can call functions. Since this initialization code is pretty specific to the class, it should be a function private (or maybe protected) to the class. But, since it's called to create a value before the class is constructed it can't depend on a class instance to exist, hence no this pointer. That means it needs to be a static member function.

现在, myVec.size()的类型为 std :: vector< Example *> :: size_t ,并且该类型是无符号的。而且您使用的哨兵值为-1,不是。而且您将其存储在 int 中,该大小可能不合适。如果向量较小,则可能不是问题。但是,如果矢量根据外部输入获取尺寸,或者您不知道矢量将获得多大的尺寸,或其他许多因素,那么这将成为一个问题。您应该考虑一下并相应地调整代码。

Now, the type of myVec.size() is std::vector<Example*>::size_t, and that type is unsigned. And you're using a sentinel value of -1, which isn't. And you're storing it in an int which may not be the right size to hold it anyway. If your vector is small, this likely isn't an issue. But if your vector acquires a size based on external input, or if you don't know how large it will get, or any number of other factors, this will become an issue. You should be thinking about that and adjusting your code accordingly.

这篇关于C ++在类构造函数中定义常量成员变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆