从成员函数修改“static const int* const”类型的数据

Modifying a data of type "static const int* const" from a member function

提问人:Cool_Cornflakes 提问时间:10/21/2022 更新时间:10/21/2022 访问量:128

问:

TLDR 问题:

class MyClass
{
public:
    void Modify()
    {
        //How can I modify MyData here 
    }

public:
    static const int* const MyData;
};

博学:

我有一个这样的班级:

class Window
{
public:
    const int* GetKeyboard()
    {
        return m_Keyboard;
    }

private:
    const int* const m_Keyboard = 0;
};

有了这个,我将访问键盘,但我想访问它。所以我写了这样的东西:WindowObjectPtr->GetKeyboard()Input::Keyboard

class Window
{
public:
    const int* GetKeyboard()
    {
        return m_Keyboard;
    }

private:
    const int* const m_Keyboard = 0;
};

const int* Input::Keyboard = 0;

class Application;
class Input
{
    friend class Application;
private:
    static void SetKeyboard(const int* k) { Keyboard = k; }

public:
    static const int* Keyboard;
};

class Application
{
public:
    void Init()
    {
        Input::SetKeyboard(m_Window.GetKeyboard());
    }

private:
    Window m_Window;
};

int main()
{
    Application application;
    application.Init();

    //Input::Keyboard
}

上面代码的唯一问题是我可以执行 Input::Keyboaord = nullptr;

所以我想将键盘的定义更改为,但无法再设置它。static const int* const Keyboard;Input::SetKeyboard

有没有类似的东西的有效版本?还是实现我想要做的事情的不同方法?mutable static const int* const Keyboard;

C++(英语:C++) 可变

评论

1赞 463035818_is_not_an_ai 10/21/2022
为什么要修改它?const
0赞 Cool_Cornflakes 10/21/2022
我只想在该函数中设置一次,再也不修改它了
1赞 code_fodder 10/21/2022
@Cool_Cornflakes - 它要么是常量,要么不是常量 - 您可以初始化带有值的常量。如果你只是想保护它的值,我想你可以把它包装成一个“写一次”的类,它可能有一个计数器,它只允许你设置一次。
1赞 user17732522 10/21/2022
为什么这甚至是一个静态成员?你有类和 ,等等。所有这些都可以创建给定类型的多个对象。如果所有对象都被迫使用相同的对象,那么该类的意义何在?换句话说,为什么没有成员,就像有一个?WindowApplicationInputInputKeyboardInputApplicationWindow
1赞 463035818_is_not_an_ai 10/21/2022
您可以初始化一个对象一次,之后就无法修改它了const

答:

2赞 user17732522 10/21/2022 #1

对象要么是,要么不是。如果是这样,则必须在其初始化中为其指定一个值,并且以后更改它的任何尝试都会导致未定义的行为(如果它一开始就不是格式不正确的)。constconst

在执行流中的某个其他点之后,无法创建对象。const

当然,你可以只添加一个对对象的引用,并在你不打算修改它以实现 const-correctness 时使用它:const

static const int* Keyboard;
static const int* const& cKeyboard = Keyboard;

现在可以用于修改,不能(没有诡计)。KeyboardcKeyboardconst_cast

但这一切似乎是完全可以避免的和混乱的,因为你可能只是一个非静态成员,有一个非静态成员,然后所有初始化都在构造函数的初始值设定项列表中发生。那么获得资格就没有问题了。KeyboardApplicationInputKeyboardconst

评论

0赞 Cool_Cornflakes 10/21/2022
谢谢老师,欣赏智慧。我将使用非静态成员方法。
0赞 user17732522 10/21/2022
@JasonLiam我将其更正为“初始化”而不是“初始化器”。当然,即使没有初始值设定项,变量可能仍然具有非空初始化(如您的问题所示)。也有一些例外情况,你实际上可以让一个对象的值完全不确定,但这只有在类设计得很糟糕并且这样的对象完全无法使用时才会发生。const
0赞 user12002570 10/21/2022
*现在没事了。
0赞 doug 10/22/2022
“一个对象要么是恒定的,要么不是。如果它是 const,则必须在其初始化中为其指定一个值,并且以后更改它的任何尝试都会导致未定义的行为“ - 自 c++20 以来,这通常不是真的。而且,对于问题中的具体示例,情况并非如此。请参阅 basic.life
0赞 user17732522 10/22/2022
@doug 尽管透明替换实际上表现得就像对象被修改了一样,但从技术上讲,它仍然涉及创建新对象。此外,静态数据成员是具有静态存储持续时间的完整对象,因此,如果它是限定的,则不允许替换它。const
1赞 463035818_is_not_an_ai 10/21/2022 #2

很多东西都可以被黑客入侵。

例如,可以有一个引用非静态成员的常量成员。私人成员可以由朋友初始化和设置。公共成员只能用于读取:staticprivate

#include<iostream>

struct foo {
        static const int& x_public;
        friend class bar;
    private:
        static int x_private;
};

const int& foo::x_public = foo::x_private;
int foo::x_private = 0;

struct bar {
    bar() {
        foo::x_private = 42;
    }
};

int main() {
    bar b;
    std::cout << foo::x_public;
}

Thgouh,我真的不建议使用它。我同意这个答案,你应该使用非静态成员。