简体   繁体   English

在初始化列表中初始化静态成员

[英]Initialize static member in initialization list

How do I make G::t static?如何使G::t静态? (eg, G::t should be of type const static int& ) G::t is defined by the constructor parameter p and not available anywhere else. (例如, G::t应该是const static int&类型) G::t由构造函数参数p定义并且在其他任何地方都不可用。

class G {
public:
    // I want to make this static.
    const int& t;

    G(const int& p);
};

G::G(const int& p) : t(p) {}

int main() {
    int a=2;
    const int& b = a;

    G g = G(b);
}

eg:例如:

const int a = 10;

class foo
{
    static const constexpr int& t = a;
};

You can't initialize static member in constructor, because constructors are for objects, not for class as whole.您不能在构造函数中初始化静态成员,因为构造函数是针对对象的,而不是针对整个类的。

Why are you even using a constructor if you want to set static members to be used by static functions?如果您想设置静态成员供静态函数使用,为什么还要使用构造函数? That's not what constructors are for.这不是构造函数的用途。 You definitely can't initialize a static member in an initializer-list, because that would mean it got initialized every time you constructed another object.你绝对不能在初始化列表中初始化一个静态成员,因为这意味着每次你构造另一个对象时它都会被初始化。 (Just think about the difference between per-class static data and per-instance data and it should be obvious why the question makes no sense). (想想每类静态数据和每实例数据之间的区别,为什么这个问题没有意义应该很明显)。

You could use a static local, which is initialized on first use so can be initialized at run-time, and then can be accessed by the static member functions:您可以使用静态本地,它在第一次使用时初始化,因此可以在运行时初始化,然后可以由静态成员函数访问:

class G {
public:
    static int t(const int& p = 0, bool set = false);

    G(const int& p);
};

G::G(const int& p) { t(p, true); }

int G::t(const int& p, bool set)
{
    static bool is_set = false;
    if (!is_set)
    {
        if (!set)
            throw std::logic_error("Cannot use G::t before it is set");
    }
    else if (set)
        throw std::logic_error("Cannot set G::t more than once");
    static const int tt = p;
    set = true;
    return tt;
}

int main() {
    int a=2;
    const int& b = a;

    G g = G(b);
    int t = G::t();
}

But this is a horrible hack, you should think carefully about your design and whether using a constructor is appropriate here, or even if using a class is appropriate.但这是一个可怕的黑客,你应该仔细考虑你的设计,以及在这里使用构造函数是否合适,甚至使用类是否合适。

The member initializer list can only be used to initialize instance variables, so if t is static, you can only reassign it in the constructor body.成员初始化列表只能用于初始化实例变量,所以如果t是静态的,只能在构造函数体中重新赋值

And because references can't be reassigned, you have to use a pointer.并且因为引用不能被重新分配,所以你必须使用指针。 A reference_wrapper doesn't work because it would need to be statically initialized (unless you have a global int that you can use for that).一个reference_wrapper不起作用,因为它需要静态初始化(除非你有一个可以用于它的全局 int )。

Eg例如

class G {
public:
    static const int* t;

    G(const int& p);
};

const int* G::t; // definition in .cpp

G::G(const int& p) {
    t = &p;
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM