![]() |
![]() |
#1 (permalink) |
Rookie
Location: Oxford, UK
|
[c++] classes and static const arrays
I'm relatively new to C++ (but not programming in general), and I'm trying to use classes with static arrays as members like so:
Base class (eg dog) with function print_data() which prints data from an array. Derived classes (eg spaniel, collie) with static const data in the array. So all collies have the same, and all spaniels have the same - but everything is printed via dog::print_data(). eg (and this code doesn't work): Code:
class dog { public: void print_data(); }; class collie : public dog { public: static const int array[]; }; class spaniel : public dog { public: static const int array[]; }; const int spaniel::array[2]={111,222}; const int collie::array[2]={333,444}; void dog::print_data() { cout << array[0] << "\n"; cout << array[1] << "\n"; } Thanks for any input. EDIT: Realised this is going to cause problems with any vars (not just arrays). I used arrays as the example as I'd been having such trouble initialising them for the class - ie you can't use 'static const int array[2]={111,222};' as part of a class definition. EDIT2: Removed the bloody smilies to make Knifemissile's later comment look a bit random :)
__________________
I can't understand why people are frightened of new ideas. I'm frightened of the old ones. -- John Cage (1912 - 1992) Last edited by cliche; 05-09-2004 at 11:00 PM.. |
![]() |
![]() |
#2 (permalink) |
I am Winter Born
Location: Alexandria, VA
|
Static variables in classes don't work the same as static variables in C. A static variable in C++, declared as a class member, means that it is shared amongst all instances of the class.
Perhaps a better idea: Code:
class Dog { protected: int array[2]; public: inline void print_array() { cout << array[0] << endl << array[1] << endl; } }; class Collie : public Dog { public: Collie() { // override constructor array[0] = 5; array[1] = 6; } }; class Spaniel : public Dog { public: Spaniel() { array[0] = 7; array[1] = 8; } }; int main() { Collie c; Spaniel s; c.print_array(); s.print_array(); return 0; }
__________________
Eat antimatter, Posleen-boy! Last edited by Pragma; 05-09-2004 at 08:29 AM.. |
![]() |
![]() |
#3 (permalink) | |
Rookie
Location: Oxford, UK
|
Quote:
The only way I've found to do it so far is to declare the array as static within each derived class, and have a pointer variable in the base class which is set by the constructor function. Whilst that only wastes one 'int' per instance, it doesn't seem to take advantage of the const-ness of the data, and seems to be the Wrong Way of doing things...
__________________
I can't understand why people are frightened of new ideas. I'm frightened of the old ones. -- John Cage (1912 - 1992) |
|
![]() |
![]() |
#4 (permalink) |
I am Winter Born
Location: Alexandria, VA
|
What are you doing that requires it? The only real times you want to conserve memory are when you're doing massive applications. Saving 4 bytes of data per instance of the class is really nothing to worry about.
I'm still not understanding what you're doing - but you're confusing the hell out of me and are making things needlessly complex.
__________________
Eat antimatter, Posleen-boy! |
![]() |
![]() |
#5 (permalink) |
Location: Waterloo, Ontario
|
Pragma, that is a terrible attitude to have. You remind me of the story of the college instructor who was teaching his class how to write a linked list. When one of his students kindly remarked that his implementation leaked memory, he quickly stammered "Oh--well, no one worries about memory leaks, anymore..."
Of course, this is a total lie. People do worry about memory leaks, even in an age of cheap memory. A similar lesson lies here. If each class has a constant table, there's no reason not to make it static... So, to that end, try something like this: Code:
class dog
{
private: // it does no harm to explicitly declare access privilege...

 /*
 I don't know how well you know C++ but there are a few things to note.

 First, the const keyword modifies the thing to its _left_
 It's only a hack that, if there's nothing to its left, it modifies what's to its right.

 Second, private member functions can be _defined_ by child classes, they
 just can't be _called_ by child classes. See the distinction?

 Thirdly, the "= 0" modifyier, if you've never seen it before, means
 that the function has no definition. That means you can't actually make
 an instance of dog. You must make instances which define the "= 0" member
 function--typically the children...

 I hope this all makes sense to you! */
 int const * get_array_data() = 0;

public:
 void print_data();
};


class collie : public dog
{
private:
 static int const array[]; // there's no reason to make this public!

 int const * get_array_data()
 {
 return array;
 }
};

// keep your variables near the clases you define them in!
int const collie::array[2]={333,444};


class spaniel : public dog
{
private:
 static int const array[]; // there's no reason to make this public!

 int const * get_array_data()
 {
 return array;
 }
};

int const spaniel::array[2]={111,222};


void dog::print_data()
{
 int const * array = get_array_data();
 cout << array[0] << "\n";
 cout << array[1] << "\n";
}

 I'm tempted to say, from your question, cliche, that you have a good intuition for writing maintainable code. Then again, you admitted you're not a beginner programmer so, perhaps, that's why... Oh--and, please, be careful with your smileys! ...edited for clarity and correctness... Last edited by KnifeMissile; 05-13-2004 at 08:58 PM.. |
![]() |
![]() |
#6 (permalink) |
I am Winter Born
Location: Alexandria, VA
|
My apologies, it is a bad attitude to have. I've been programming nonstop for the past several days on several projects and am not thinking quite right about everything.
![]() Upon re-reading what cliche was intending to do, I agree with your implementation, KnifeMissle.
__________________
Eat antimatter, Posleen-boy! |
![]() |
![]() |
#7 (permalink) |
Rookie
Location: Oxford, UK
|
Thanks for the help, KnifeMissile, the compliment and the advice about smilies (I hadn't seen the option :) )
This is what I came up with myself - I'm not sure if it's just another instance of your result but it seems to work too: Code:
class dog { public: int const *numb; void print_data() { cout << *numb << "\n"; }; }; class collie : public dog { public: static int const numb; collie(){dog::numb=&collie::int_numb;}; }; int const collie::int_numb=111; class spaniel : public dog { public: static int const int_numb; spaniel(){dog::numb=&spaniel::int_numb;}; }; int const spaniel::int_numb=555; On reading around I've decided what I really was looking for was something like: Code:
/* not valid C++ but I'd like it to be :) */ class dog { public: virtual int numb; void print_data() { cout << numb << "\n"; }; }; class spaniel { public: static int const numb; }; /* etc.... */ EDIT to take Knifemissile's advice about const and data location... hope that's right!
__________________
I can't understand why people are frightened of new ideas. I'm frightened of the old ones. -- John Cage (1912 - 1992) Last edited by cliche; 05-09-2004 at 11:08 PM.. |
![]() |
![]() |
#8 (permalink) |
Location: Waterloo, Ontario
|
Hey, I'm glad you're actually taking my advice seriously! Too many people just ignore me...
Actually, you simply implemented your initial second post, after Pragma's first response. It's not a bad idea except that mine uses up less memory. I was thinking of preemptively responding to this idea but I wasn't sure if you'd go with it... Anyway, your solution uses a pointer per class instance where mine does no such thing. Plus, if you're just going to store an integer, you might as well just store the value instead of a pointer to the value, right? Say, what's up with your new ultra-condensed indentation style? Okay, I'm going to take a cheeky someone's advice and go to sleep... |
![]() |
![]() |
#9 (permalink) |
Rookie
Location: Oxford, UK
|
(Once you've woken up) Just wondering exactly how your solution gets compiled (my previous programming experience was years of mostly 6502 and ARM assembler, C++ has started in earnest this week).
Does the compiler 'know' that your get_array_data function is essentially a constant? Is there any difference if it's declared static? (from my understanding this means one function is shared across all the instances) If you're complaining about my indentation I should show you some of my old code ![]()
__________________
I can't understand why people are frightened of new ideas. I'm frightened of the old ones. -- John Cage (1912 - 1992) |
![]() |
![]() |
#10 (permalink) |
Location: Waterloo, Ontario
|
I just mean that your indentation style in your second code post is different than your first one. You seem to have changed styles for some reason...
Anyway, how my solution gets compiled is rather complicated. It makes use of a virtual function, so a virtual function table has to be created, so I don't think it can get inlined. The problem is that the compiler can't know, at compile time, what function to call. For instance, take this piece of code: Code:
void do_something_that_includes_printing(dog* dog_obj) { // do stuff... // how can the compiler know which dog this is? dog_obj->print_data(); } int main() { dog* dog_obj = new collie(); do_something_that_includes_printing(obj); delete dog_obj; dog_obj = new spaniel(); // reusing the pointer do_something_that_includes_printing(obj); delete dog_obj; return 0; } All member functions, static or not, are shared across instances of objects. It wouldn't be much of a function if it weren't (the whole point of a function is to reuse code!). A static member function is a member function that lacks a this pointer. What that means is that, while it shares the same access privileges as other member functions, it can't access any member variables. Pretty funny, eh? Well, it makes more sense than it looks, at first... ...edited for clarity... Last edited by KnifeMissile; 05-16-2004 at 02:56 PM.. |
![]() |
![]() |
#11 (permalink) | |
Upright
|
Code Reformat.
I thought KnifeMissile's code was worth reformatting, so I did it.
Quote:
Last edited by SparkleSmite; 11-28-2007 at 11:32 AM.. Reason: I thought KnifeMissile's code was worth reformatting, so I did it. |
|
![]() |
Tags |
arrays, classes, const, static |
|
|