I’ve got class which is using plain-only-data struct with const variables and I’m not sure, if I’m allocating these structures in a proper way. It looks more or less like:
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
struct some_const_struct {
const int arg1;
const int arg2;
};
class which_is_using_above_struct {
private:
some_const_struct* m_member;
const some_const_struct* const m_const_member;
public:
const some_const_struct& get_member() const { return *m_member; }
const some_const_struct& get_const_member() const { return *m_const_member; }
void set_member(const int a, const int b) {
if(m_member != NULL) {
delete m_member;
m_member = NULL;
}
m_member = new some_const_struct((some_const_struct){a, b});
}
explicit which_is_using_above_struct(const int a, const int b)
: m_const_member(new some_const_struct((const some_const_struct){a, b})) {
m_member = NULL;
}
~which_is_using_above_struct() {
if(m_member != NULL) {
delete m_member;
}
if(m_const_member != NULL) {
delete m_const_member;
}
}
};
int main() {
which_is_using_above_struct c(1, 2);
c.set_member(3, 4);
cout << "m_member.arg1 = " << c.get_member().arg1 << endl;
cout << "m_member.arg2 = " << c.get_member().arg2 << endl;
cout << "m_const_member.arg1 = " << c.get_const_member().arg1 << endl;
cout << "m_const_member.arg2 = " << c.get_const_member().arg2 << endl;
return 0;
}
I’m just not quite sure if the statement:
m_member = new some_const_struct((some_const_struct){a, b});
doesn’t produce unnessesary use of some_const_struct’s copy constructor, ergo allocating that struct twice. What do you think? And is it reasonable to make that struct’s members const? (they’re not supposed to change in their lifetime at all)
Such syntax is not allowed by standard C++ and is only supported by your compiler as an extension.
I think the only standard-compiliant way with the current standard1 would be to use copy-construction and a helper function to initialize the struct in a portable way.2
I think you should just make your life easier and not use const members, particularly since
set_memberallows you to modify the fields anyway (at a great cost both coding- and performance-wise).You could also give constructors3 to the classes, but then they won’t be Plain Old Data structs any more, if that is important to you. (Actually I’m not sure whether a struct with const members qualifies as POD in the first place: e.g memsetting and memcpying such a struct would violate the constness of the members, but should be legal things to do with real POD structs.)
1 AFAIK, C++0x will revise the rules concerning
{}in initialization, making it easier to achieve what you want.2 Under favorable conditions, the compiler should be able to optimize out the needless copy, transforming it into the exact equivalent of what you are doing.
3 Comeau’s compiler appears to be very helpful. It even tells you what (it thinks) you should do:
warning: class "some_const_struct" defines no constructor to initialize the following: ...