Proper way to put a C++ object inside a struct initialization?
-
I working in an embedded environment (STM32 microcontroller) and I compile using GCC (STM32CubeIDE). I want to put a C++ object inside a struct and this is the only way I could get it to compile:
namespace MyNamespace {
class MyObject
{
int m_i;
public:
MyObject(int i):m_i(i){}
MyObject(const MyObject&) = delete;
};
}typedef struct {
MyNamespace::MyObject* MyObject;
} MyStruct_s;static MyStruct_s MyStruct = {new MyNamespace::MyObject(0) };
However, I'm having strange hanging issues in my code and I suspect the code above might be the cause. Is the code above legal or will it corrupt RAM? If so, what's the correct way to do it? Ideally I'd like to have the whole object inside the struct, not just a pointer to it.
-
I working in an embedded environment (STM32 microcontroller) and I compile using GCC (STM32CubeIDE). I want to put a C++ object inside a struct and this is the only way I could get it to compile:
namespace MyNamespace {
class MyObject
{
int m_i;
public:
MyObject(int i):m_i(i){}
MyObject(const MyObject&) = delete;
};
}typedef struct {
MyNamespace::MyObject* MyObject;
} MyStruct_s;static MyStruct_s MyStruct = {new MyNamespace::MyObject(0) };
However, I'm having strange hanging issues in my code and I suspect the code above might be the cause. Is the code above legal or will it corrupt RAM? If so, what's the correct way to do it? Ideally I'd like to have the whole object inside the struct, not just a pointer to it.
As matter of fact, you don't need a pointer. Try
#include using namespace std;
namespace MyNamespace
{
class MyObject
{
int m_i;
public:
MyObject(int i):m_i(i){}
int get_i(){return m_i;}
};
}struct MyStruct
{
MyNamespace::MyObject myObject;
};static MyStruct s_myStruct = { MyNamespace::MyObject(5) };
// this probably won't run on a microcontroller...
int main()
{
cout << s_myStruct.myObject.get_i() << endl;
}"In testa che avete, Signor di Ceprano?" -- Rigoletto
-
I working in an embedded environment (STM32 microcontroller) and I compile using GCC (STM32CubeIDE). I want to put a C++ object inside a struct and this is the only way I could get it to compile:
namespace MyNamespace {
class MyObject
{
int m_i;
public:
MyObject(int i):m_i(i){}
MyObject(const MyObject&) = delete;
};
}typedef struct {
MyNamespace::MyObject* MyObject;
} MyStruct_s;static MyStruct_s MyStruct = {new MyNamespace::MyObject(0) };
However, I'm having strange hanging issues in my code and I suspect the code above might be the cause. Is the code above legal or will it corrupt RAM? If so, what's the correct way to do it? Ideally I'd like to have the whole object inside the struct, not just a pointer to it.
Your code is correct but dangerous. You don’t control the time when
myStruct
is initialized. There are various methods to control it. My preferred method is the nifty counter[^]. In general, you can include objects in structures. As a matter of fact C++ makes little difference between the two. Without seeing the code, I suspect that your problem is that you don’t have a default constructor for your object. Let me explain: as you don’t have a default constructor formyStruct
, the compiler will synthesize one that invokes the default constructor for any included non-trivial members. If your object doesn’t have a default constructor, the compiler complains.Mircea
-
As matter of fact, you don't need a pointer. Try
#include using namespace std;
namespace MyNamespace
{
class MyObject
{
int m_i;
public:
MyObject(int i):m_i(i){}
int get_i(){return m_i;}
};
}struct MyStruct
{
MyNamespace::MyObject myObject;
};static MyStruct s_myStruct = { MyNamespace::MyObject(5) };
// this probably won't run on a microcontroller...
int main()
{
cout << s_myStruct.myObject.get_i() << endl;
}"In testa che avete, Signor di Ceprano?" -- Rigoletto
I'm able to compile your code example. However, I just realized that I had forgotten the following line of code (I didn't think it was important) in my first post (I have added it now):
MyObject(const MyObject&) = delete;
I'm not good at programming C++ so I'm not sure what that line does. After I have added this line, I get the following error message with your code example: "use of deleted function 'MyNamespace::MyObject::MyObject(const MyNamespace::MyObject&)"
-
Your code is correct but dangerous. You don’t control the time when
myStruct
is initialized. There are various methods to control it. My preferred method is the nifty counter[^]. In general, you can include objects in structures. As a matter of fact C++ makes little difference between the two. Without seeing the code, I suspect that your problem is that you don’t have a default constructor for your object. Let me explain: as you don’t have a default constructor formyStruct
, the compiler will synthesize one that invokes the default constructor for any included non-trivial members. If your object doesn’t have a default constructor, the compiler complains.Mircea
-
I'm able to compile your code example. However, I just realized that I had forgotten the following line of code (I didn't think it was important) in my first post (I have added it now):
MyObject(const MyObject&) = delete;
I'm not good at programming C++ so I'm not sure what that line does. After I have added this line, I get the following error message with your code example: "use of deleted function 'MyNamespace::MyObject::MyObject(const MyNamespace::MyObject&)"
The line prohibits compiler from copying
MyObject
objects. Look at the following code to better understand what's going on:namespace MyNamespace
{
class MyObject
{
int m_i;
public:
MyObject (int i) :m_i (i + 1) { cout << "MyObject constructor i=" << i << endl; }
MyObject (const MyObject&) = delete; //these objects cannot be copied
int get_i () const { return m_i; }
};
}struct MyStruct
{
MyStruct (const MyNamespace::MyObject& r) //tell compiler how to build a MyStruct
: myObject (r.get_i ()) //cannot copy myObject so I just make a new one
{ cout << "MyStruct constructor" << endl; }MyNamespace::MyObject myObject;
};static MyStruct s_myStruct { MyNamespace::MyObject (5) };
//created a MyObject, then created a second one and finally finished construction of myStruct// this probably won't run on a microcontroller...
int main ()
{
cout << s_myStruct.myObject.get_i () << endl;
}The output is:
MyObject constructor i=5
MyObject constructor i=6
MyStruct constructor
7Mircea
-
I'm able to compile your code example. However, I just realized that I had forgotten the following line of code (I didn't think it was important) in my first post (I have added it now):
MyObject(const MyObject&) = delete;
I'm not good at programming C++ so I'm not sure what that line does. After I have added this line, I get the following error message with your code example: "use of deleted function 'MyNamespace::MyObject::MyObject(const MyNamespace::MyObject&)"
That disables the (otherwise automatically generated) copy constructor. Not sure why you need that. Have a look at https://stackoverflow.com/questions/34291938/why-and-when-delete-copy-constructor-and-operator[^].
"In testa che avete, Signor di Ceprano?" -- Rigoletto
-
That disables the (otherwise automatically generated) copy constructor. Not sure why you need that. Have a look at https://stackoverflow.com/questions/34291938/why-and-when-delete-copy-constructor-and-operator[^].
"In testa che avete, Signor di Ceprano?" -- Rigoletto
-
The line prohibits compiler from copying
MyObject
objects. Look at the following code to better understand what's going on:namespace MyNamespace
{
class MyObject
{
int m_i;
public:
MyObject (int i) :m_i (i + 1) { cout << "MyObject constructor i=" << i << endl; }
MyObject (const MyObject&) = delete; //these objects cannot be copied
int get_i () const { return m_i; }
};
}struct MyStruct
{
MyStruct (const MyNamespace::MyObject& r) //tell compiler how to build a MyStruct
: myObject (r.get_i ()) //cannot copy myObject so I just make a new one
{ cout << "MyStruct constructor" << endl; }MyNamespace::MyObject myObject;
};static MyStruct s_myStruct { MyNamespace::MyObject (5) };
//created a MyObject, then created a second one and finally finished construction of myStruct// this probably won't run on a microcontroller...
int main ()
{
cout << s_myStruct.myObject.get_i () << endl;
}The output is:
MyObject constructor i=5
MyObject constructor i=6
MyStruct constructor
7Mircea