What's new

Constant members

Doomulation

?????????????????????????
I was wondering if there's a way to create const data members in either a struct or a class. The thing is that I wish to create a struct or class with members that I will use fwrite to output directly to the disk. I'm trying to copy a specific format here. Some of the data must be the same always, so I'm trying to make them const and initialize them. Like so:

Code:
class test
{
public:
	test();
	void test_fnc();
private:
	const char posttyp[2];
	char datum[8];
	char autogiro[8];
	char empty1[44];
	char mottagare_kundnr[6];
	char mottagare_pgnr[10];
	char empty2[2];
} _test;

Since posttyp is const, I have no way to initialize it. Static data does not work on arrays, either. Plus it would destroy the purpose of a class to do this. So is there a way to initialize the data while retaining const, or must it be removed for this to work? I suppose I could bypass const with the following:

Code:
memcpy((void*)&posttyp,"01",2);
(Yes, I'm aware that it is actually 3 bytes, but it must not include the NULL char.)
Only problem is that the class fails to compile when using const data members :/

EDIT:
Did some more tests... it appears that if you put any const member in a struct or class, you'll be needing your own constructor for it. And if you do declare one, it'll complain that the const members couldn't be initialized (even if you do not specify anything to initialize them with.)
 
Last edited:

Pontifice

Learning
maybe you could use static ?
It's the same for all the objects from the class, and i think it lets you initialize them.
Code:
static char posttyp[2];
 
OP
Doomulation

Doomulation

?????????????????????????
1: As I described, static cannot be used on arrays. I tried that.
2: I'd rather avoid it as it defies the usage of a class.
 

Pontifice

Learning
this works for me
Code:
#include <cstdlib>
#include <iostream>
using namespace std;


class test
{
public:
       
	test(){
          
    }
	void test_fnc(){
      cout << posttyp[0] << " " << posttyp[1] << " ";  
         }
    static void initarray(){
     posttyp[0] = 'a';      
     posttyp[1] = 'b';    
         
    }
    void initarrayb(){
     posttyp[0] = 'b';      
     posttyp[1] = 'c';    
         
    }          
private:
	static char posttyp[2];
	char datum[8];
	char autogiro[8];
	char empty1[44];
	char mottagare_kundnr[6];
	char mottagare_pgnr[10];
	char empty2[2];
} _test;

char test::posttyp[2]; 
   

int main(int argc, char *argv[])
{
    test prueba;
    //prueba.test_fnc();
    test::initarray();
    prueba.test_fnc();
    prueba.initarrayb();
    prueba.test_fnc();
    // these don't work because posttyp is private
    //cout << " " << prueba.posttyp[0];
    //cout << " " << test::posttyp[0];
    system("PAUSE");
    return EXIT_SUCCESS;
}

2: I'd rather avoid it as it defies the usage of a class.
I'm not sure what you are trying to say ( probably my fault )
 
Last edited:

zenogais

New member
Hmm, I remember using const class members before and I did smth like this:

Code:
class Blah
{
    public:
        Blah();
    ...
    private:
        const char* _name;
};

// Then...

Blah::Blah()
    : _name("Blah")
{
}

So maybe you could do something like that, using a char* of a constant size instead, or making two seperate const char's.
 
Last edited:
OP
Doomulation

Doomulation

?????????????????????????
I say I don't use static because the data is the same in ALL classes. I don't want that.
The reason I don't use pointers is that I wish to do fwrite(this); later. It won't do it right if it's pointers.
Any other tips? Otherwise I guess I'll go with the normal non-const solution.
 

Pontifice

Learning
Ouch, now i get it, no static, sorry i woke up early and i was to sleepy to see it clearly.

P.D. sorry, i read it again and it is clear .... i'm ashame of myself.... :blush:
 
Last edited:
OP
Doomulation

Doomulation

?????????????????????????
Hehe. Now, now, don't worry. Static data isn't all that bad if it doesn't need to change. Since the const members will always hold the same data, it's quite alright.
 

ChaosBlade

My Heart Chose.. Revenge.
zenogais's way is the correct one, you initialize const data members using M.I.L , Member Initialization Lists. After defining a class constructor, you add the MIL line:

Class CClass
{
...
}

CClass::CClass()
: m_DataMemberName(value)
{
...
}
 

Slougi

New member
Doomulation said:
I say I don't use static because the data is the same in ALL classes. I don't want that.
The reason I don't use pointers is that I wish to do fwrite(this); later. It won't do it right if it's pointers.
Any other tips? Otherwise I guess I'll go with the normal non-const solution.
Doom, doing fwrite(this) is an extremely bad approach. Just add one function or variable to the class and the output produced will be different. Your safes will be version dependant this way. Better to overload the << operator or create a save function that writes the data correctly.
 

zenogais

New member
Slougi is 100% correct, serializing an entire object to a file 9 times out of 10 won't work as expected and the program will explode in your face. Best to overload the stream operators or create your own functions and then write each individual member to the file. The "easy" solution (writing the entire object out to a file) won't work.
 

Cyberman

Moderator
Moderator
Doomulation said:
1: As I described, static cannot be used on arrays. I tried that.
2: I'd rather avoid it as it defies the usage of a class.
Doom maybe you should just tell us what you are trying to do to begin with? It seems like you are doing things the 'challenging' way so it might help to clarify what you are attempting to do.

Are you making an Abstract Base Class?

Cyb
 

ChaosBlade

My Heart Chose.. Revenge.
Hmm, ive written whole objects to memory\file before and havent encountered problems. Then again, i dont think any of them had variable sizes so that might be the difference.
 
OP
Doomulation

Doomulation

?????????????????????????
Cyberman said:
Doom maybe you should just tell us what you are trying to do to begin with? It seems like you are doing things the 'challenging' way so it might help to clarify what you are attempting to do.

Are you making an Abstract Base Class?

Cyb
Alright then, I will :)
I got a little task to write a file according to specs. Now the usual way of writing data to a file and reading it back again would be to use a struct and fwrite. That's why I need the variables to be fixed-length. Only some data never change in this file, hence why I want const and pre-initialized data. Get my point?

That struct is the header written to the file, containing the data to write. This is an example of how the file looks (only the header):

Code:
0120050309AUTOGIRO                                            1234560058019696

Oh and yes, I like to do things the "challenging" way. That's what I like about C++: its power! I feel limited if I use languages such as visual basic :(

zenogais's way is the correct one, you initialize const data members using M.I.L , Member Initialization Lists. After defining a class constructor, you add the MIL line:

Class CClass
{
...
}

CClass::CClass()
: m_DataMemberName(value)
{
...
I always initalize variables this way. But zenogais example has two flaws:
1) It musn't be a pointer, or the address of the value will be printed instead. I wish to avoid this if possible.
2) Only the variable itself is const, meaning that you cannot change the address, but you CAN change the value it's pointing to!

Doom, doing fwrite(this) is an extremely bad approach. Just add one function or variable to the class and the output produced will be different. Your safes will be version dependant this way. Better to overload the << operator or create a save function that writes the data correctly.

Slougi is 100% correct, serializing an entire object to a file 9 times out of 10 won't work as expected and the program will explode in your face. Best to overload the stream operators or create your own functions and then write each individual member to the file. The "easy" solution (writing the entire object out to a file) won't work.
Hmm, thanks for the heads up. But afaik, classes are like structs. The functions are stored elsewhere and not in the class. If I limit the size enough, it should only write the data in the class. I can't be 100% sure, but I'll be sure to test this!

Now, I'll go make some tests, and report back later what I uncover!
EDIT: Hmmm... no, I don't see a problem. Code:

Code:
class test2
{
protected:
	test2();
	char test_str[21];
};

test2::test2()
{
	 memcpy(&test_str,"this is a test string",21);
}

class test: public test2
{
public:
	test();
	void test_fnc2();
private:
	char posttyp[2];
	char datum[8];
	char autogiro[8];
	char empty1[44];
	char mottagare_kundnr[6];
	char mottagare_pgnr[10];
	char empty2[2];
} _test;

test::test()
{
	memcpy(&posttyp,"01",2);
	memcpy(&datum,"20050310",8);
	memcpy(&autogiro,"AUTOGIRO",8);
	memset(&empty1,' ',44);
	memcpy(&mottagare_kundnr,"123456",6);
	memcpy(&mottagare_pgnr,"0058019696",10);
	memset(empty2,' ',2);
}

void test_fnc()
{
	//MessageBox(NULL,"hi!","hi!",NULL);
	FILE* f = fopen("C:\\test.txt","w");
	fwrite(&_test,sizeof(_test),1,f);
	fclose(f);
}

Also tried this:
Code:
...
void test_fnc()
{
	//MessageBox(NULL,"hi!","hi!",NULL);
	_test.test_fnc2();
}

void test::test_fnc2()
{
	FILE* f = fopen("C:\\test.txt","w");
	fwrite(this,sizeof(*this),1,f);
	fclose(f);
}

Output:
Code:
this is a test string0120050310AUTOGIRO                                            1234560058019696
Exactly as I expected it. No problems. It's perfectly safe to use fwrite on classes!
 
Last edited:
OP
Doomulation

Doomulation

?????????????????????????
Another problem that's bugging me also is that the IDE (or something!) seems to ignore the manifest. The result is a program that looks just as usual programs that do not use the XP controls. Yes, the file is in the project and everything. It was generated by the MFC App Wiz, and yet, the manifest does not work. How come? Yes, I'm using the 2003 .NET IDE. I had no such problems with this using the 2002 .NET IDE.
 

Top