![]() |
[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 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 :) |
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 { |
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... |
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. |
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... |
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. |
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 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 :) */ EDIT to take Knifemissile's advice about const and data location... hope that's right! |
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... |
(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 ;) Though people have remarked it's the heaviest-documented assembler they've seen... |
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... |
Code Reformat.
I thought KnifeMissile's code was worth reformatting, so I did it.
Quote:
|
All times are GMT -8. The time now is 10:24 PM. |
Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2025, vBulletin Solutions, Inc.
Search Engine Optimization by vBSEO 3.6.0 PL2
© 2002-2012 Tilted Forum Project