C 在不构造它的情况下创建静态对象(无需分配)

C++ create static object without constructing it (without allocation)

本文关键字:对象 静态 分配 创建 情况下      更新时间:2023-10-16

im编写无法使用内存分配的嵌入式代码!同样,静态对象(因此在微控制器执行了所有初始化之前构建的主函数)应在初始化后的主内构建,而不是之前。

人们建议的唯一解决方案是使用静态对象指针,并在初始化过程中分配(用新的)分配(使用新的)。既然我没有其他选择,没有其他解决方案?

我想做的如下:

class A
{
public:
  A(int a, bool b)
  : myVal1(a), myVal2(b)
  {
  }
private:
  int myVal1;
  bool myVal2;
}
class B
{
public:
  B(char x)
  : myChar1(x) // <-- NO CONSTRUCTION, NO PARAMETER OF MYOBJECTA
  {
  }
  void init()
  {
    // now i wanna construct myObjectA
    myObjectA(123, false);
  }
private:
  char myChar1;
  A myObjectA; // <-- NO CONSTRUCTION, NO PARAMETER
}
static B myObjectB('F'); // <-- NO CONSTRUCTION, NO PARAMETER OF MYOBJECTA
void global_init()
{
// ... do before construction      
  // now i wanna construct myObjectA
  myObjectB.init();
  //... do after construction
}

您可以使用足够大的存储区域来创建A的实例和新的位置以控制您创建它的时间。
例如:

#include #include

struct A {
    A(int a, bool b): myVal1(a), myVal2(b) {}
    void foo() {}
private:
    int myVal1;
    bool myVal2;
};
struct B {
    B(char x): myChar1(x) {}
    ~B() { if(ptr) { ptr->~A(); } }
    void init() {
        ptr = new (&storage) A{123, false};
    }
    A * myObjectA() {
        return ptr;
    }
private:
    char myChar1;
    std::aligned_storage_t<sizeof(A), alignof(A)> storage;
    A *ptr{nullptr};
};
static B myObjectB('F');
void global_init() {
    // ... do before construction      
    // now i wanna construct myObjectA
    myObjectB.init();
    //... do after construction
}
int main() {
    global_init();
    myObjectB.myObjectA()->foo();
}

这个不会分配内存(如果我得到正确的意思),而A的实例实际上是在B::init中创建的(这似乎是您在您在您的写作中的要求问题)。


如果您可以访问支持C 17的编译器,或者可以使用C Boost库,则std::optional是另一个答案中建议的有效替代方案。无论如何,您没有指定遵守标准的修订,因此...在任何情况下,这都是一种方法。

您有可用的升级吗?

#include <boost/optional.hpp>
class A
{
public:
  A(int a, bool b)
  : myVal1(a), myVal2(b)
  {
  }
private:
  int myVal1;
  bool myVal2;
};
class B
{
public:
  B(char x)
  : myChar1(x) // <-- NO CONSTRUCTION, NO PARAMETER OF MYOBJECTA
  {
  }
  A& getA() {
      assert(myObjectA);
      return myObjectA.get();
  }
  void init()
  {
    // now i wanna construct myObjectA
    myObjectA.emplace(123, false);
  }
private:
  char myChar1;
  boost::optional<A> myObjectA; // <-- NO CONSTRUCTION, NO PARAMETER
};
static B myObjectB('F'); // <-- NO CONSTRUCTION, NO PARAMETER OF MYOBJECTA
void global_init()
{
// ... do before construction      
  // now i wanna construct myObjectA
  myObjectB.init();
  //... do after construction
}
int main()
{
    global_init();
}