BWIGLEY said:
I have an object (dsply_stuff), which inherits msg_lin and has a
variable count. I want to be able to access count from functions
within msg_lin, How would I do this? I thought putting 'virtual int
count;' in msg_lin might work, but I guess it doesn't...
#include <cstdio>
class msg_lin {
/*Doesn't work right, I want count to be the dsply_stuff::count,
not msg_lin::count*/
virtual int count;
public:
bool msg(void);
};
#endif
bool msg_lin::msg(void) {
/*this is supposed to display dsply_stuff::count, not msg_lin's
*/
printf("count: %d\n", count);
}
class dsply_stuff : public msg_lin {
int count;
public:
dsply_stuff(int var);
};
#endif
dsply_stuff::dsply_stuff(int var) {
count = var;
}
int main(void) {
dsply_stuff display(7);
dsply_stuff *p_dsply;
p_dsply = &display;
p_dsply->msg(); //should display count: 7
getchar();
}
Okay, you have a base class that needs a variable defined in the derived.
So, why not just define it in your base? From your description later, it
seems it's actually a pointer. That's fine, just have it initialized in the
base's constructor.
#include <cstdio>
class msg_lin {
/*Doesn't work right, I want count to be the dsply_stuff::count,
not msg_lin::count*/
// > virtual int count;
protected:
int* count; // or whatever pointer it is
msg_lin( int* countP): count( countP ) {}; // count gets initialized in
constructor
// since it's a protected constructor, only a derived class can
instantize
public:
bool msg(void);
};
#endif
// > bool msg_lin::msg(void) {
bool msg_lin::msg() {
// void is not needed, nor desired, in C++ as a parm.
/*this is supposed to display dsply_stuff::count, not msg_lin's
*/
//> printf("count: %d\n", count);
printf("count %d\n", *count ); // Just cause it's a ponter now
}
class dsply_stuff : public msg_lin {
// > int count;
// don't need anymore, it's in base now
public:
dsply_stuff(int* var);
};
#endif
//> dsply_stuff::dsply_stuff(int var) {
dsply_stuf::dsply_stuff( int* var ): msg_lin( var ) {
// and that's where the magic comes in. The int* in msg_line gets
initialized here in
// the derived classe's initialization list.
count = var;
}
int main(void) {
dsply_stuff display(7);
dsply_stuff *p_dsply;
p_dsply = &display;
p_dsply->msg(); //should display count: 7
getchar();
}
Since that may be a little confusing because of all the code and comments,
I'll try to explain it a little better, if I can. If a base class needs a
variable defined/declared by a derived class, it generally means it just has
to be constructed in the base class's constructor, and then it is up to the
derived class to initalize the base class. It's generally better to use a
reference instead of a pointer, but same thing applies.
Here's an example:
class Base
{
public:
Base( sometype* somevar ): SomeVar( somevar ) {};
private:
sometype* SomeVar;
};
Now, it is impossible to instantize that Base class without giving it a
paramter, in this case a sometype reference. This would NOT compile: - for
this I did a
typedef int sometype;
class Derived: public Base
{
};
int main(void)
{
Derived d;
}
My compiler gives me:
warning C4510: 'Derived' : default constructor could not be generated
see declaration of 'Derived'
warning C4610: class 'Derived' can never be instantiated - user defined
constructor required
error C2512: 'Derived' : no appropriate default constructor available
Which is good, which is what we want. SomeVar HAS to be intialized in the
derived constructor, just like you want.
Now, changed it to this:
class Derived: public Base
{
public:
Derived( int* p ): Base(p) {};
};
int main(void)
{
int i;
Derived d(&i);
std::string wait;
std::getline( std::cin, wait );
}
and it compiles happily. If you want Base to only be able to be instantized
by a derived class, make the constructor protected.
class Base
{
protected:
Base( sometype* somevar ): SomeVar( somevar ) {};
private:
sometype* SomeVar;
};
and, again, it compiles and runs happily. But I can't do this:
int main()
{
int i;
Base b(&i);
}
My compiler telling me
error C2248: 'Base::Base' : cannot access protected member declared in class
'Base'
see declaration of 'Base::Base'
see declaration of 'Base'
This is all through the magic of "initalization lists". It won't work this
way without them.