【问题标题】:Correct way to initialize a const member初始化 const 成员的正确方法
【发布时间】:2018-11-24 22:56:03
【问题描述】:

我正在开发图形库,目前正在优化。据我所知(如果我错了,请纠正我),在 GCC/G++ 编译器中,只读变量和常量放在 flash 的文本部分中(我正在研究基于 ARM 处理器的嵌入式系统)和这提供了一种有效的方式来保存大量数据,而不是依赖于 RAM。

因此,我需要初始化一个类中声明的 const 数组,这是我的方法:

#include <iostream>

using namespace std;

class BITMAP{
    public:
        const uint16_t *BMP; // Image for this graphic object       

        BITMAP(uint16_t *bmp) : BMP(bmp) {} // This is where I initialize the const array

};

class GFX{
    public:
        void init_bmp();
        void render();


    private:
        // Object 
        BITMAP *bmp_image;

};

void GFX::init_bmp()
{
    cout << "Setting..." << endl;
    uint16_t *BMP1 = new uint16_t[2];  
    BMP1[0] = 0xFFFF;
    BMP1[1] = 0xFFFF;
    BITMAP bmp_image(BMP1);
    cout << "done!" << endl;

    delete[] BMP1;
}

void GFX::render()
{
    for( int i=0; i<2; i++ )
    {
        cout << i << ":" << bmp_image->BMP[i] << endl;
    }
}

int main()
{
    GFX img;

    img.test();
    img.render();


    return 0;
}

每当我尝试读取BITMAP::BMP 的内容时,上面的代码都会给我一个分段错误。在上面的代码中初始化const uint16_t *BMP 的正确方法是什么?

【问题讨论】:

  • 您的问题似乎是GFX::init_bmp。它创建BMP 指针,然后将其删除。在init_bmp 之外没有什么好处。也许delete[] BMP1; 应该移到析构函数中。
  • 您无法使用 new 初始化将存储在 ROM 中的数组。查看constexprstd::array&lt;&gt;

标签: c++ constructor constants


【解决方案1】:

有两个问题:bmp_image 从未初始化,你在读取之前删除了数组。

而不是这个:

BITMAP bmp_image(BMP1);

这样做:

bmp_image = new BITMAP(BMP1);

这些指针应该在每个类的析构函数中被删除,而不是之前。

此外,您实际上并没有创建一个常量数组。您正在动态创建数组,因为您使用new。使其成为放置在文本部分中的编译时常量的一种方法是使用图像创建一个全局数组:

static const uint16_t BMP1[] = {0xFFFF, 0xFFFF};

然后将这个数组传递给BITMAP的构造函数。

【讨论】:

  • 有什么方法可以做相当于你所做的“静态 const uint16_t BMP1[] = {0xFFFF, 0xFFFF};”在运行时?该文件需要从 .jpg 打开,所以我不能在代码上真正做到这一点。
  • @LuisCruz 否。文本部分是可执行文件的一部分。如果在编译时不知道值,则无法将其放在文本部分中。
  • 我的意思是,我在编译时事先知道这些值。但是文件太大而无法“写入”十六进制值并将其放入文件中(我的计算机变得迟钝!)。有更好的方法吗?我想我需要编写自己的 makefile 来在文本部分插入图像?
  • @LuisCruz 一种方法是在头文件中定义此变量,并使用读取图像文件的脚本自动创建头文件。这样您就不必在编辑器中打开标题。如果您总是使用相同的图像,那么您只需要创建一次标题。否则,您可以在 makefile 中执行脚本。
  • 是的,我正在考虑这个问题。做一个脚本来创建头文件将是要走的路。谢谢!
【解决方案2】:

上面代码中初始化const uint16_t *BMP的正确方法是什么?

您正在正确初始化它。问题是您正在deleteing 分配的内存,这使成员指针成为悬空指针。

你可以删除线

delete[] BMP1;

解决问题。然而,管理动态分配的内存充满了问题。更喜欢使用std::vector

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多