Virtual Variables?

B

BWIGLEY

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();
}
 
I

Ian Collins

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...
Use a virtual function:

#include <iostream>

class msg_lin {
virtual int count() const = 0;
public:
void msg();
};

void msg_lin::msg(void) {
std::cout << "count: " << count() << std::endl;
}

class dsply_stuff : public msg_lin {
int value;
int count() const { return value; }

public:
dsply_stuff(int var);
};

dsply_stuff::dsply_stuff(int var) {
value = var;
}
 
L

Lionel B

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();
}

Something like this?

#include <cstdio>

class msg_lin
{
public:
virtual int get_count() const =0; // pure virtual - derived class must implement

void msg() const
{
printf("count: %d\n", get_count()); // uses derived class implementation of get_count()
}
};

class dsply_stuff : public msg_lin
{
int count;

public:
dsply_stuff(int var) : count(var) // prefer initialisation to assignment
{
}

virtual int get_count() const // implements base class pure virtual
{
return count;
}
};


int main()
{
dsply_stuff display(7);

msg_lin* p = &display;

p->msg();
}
 
W

WittyGuy

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;

It's not possible to declare a data member as virtual data member.
Compiler should've thrown compilation err, I guess.

-
Sukumar R
 
B

BWIGLEY

Ian Collins said:
Use a virtual function:

I guess I may have over simplified a little... the variable will
actually be a pointer to a display function like this(sort-of
incomplete code):


#include <iostream>

class display_object {
public:
display();
};

class msg_lin {
public:
void msg() {
p_dsply_obj->display("This text would be displayed");
}
};

class dsply_stuff : public msg_lin {
display object *p_dsply_obj;
int count() const { return value; }

public:
dsply_stuff(int var);
};

dsply_stuff::dsply_stuff(int var) {
p_dsply_obj = var;
}

int main(void) {
display_object dsply_obj
dsply_stuff display(&dsply_obj);
dsply_stuff *p_dsply;
p_dsply = &display;

p_dsply->msg(); //should display the message

getchar();
}

p_dsply_obj wouldn't need to be changed after intilization. Is there
a better way to make msg_lin know about p_daply_obj?
 
I

Ian Collins

BWIGLEY said:
I guess I may have over simplified a little... the variable will
actually be a pointer to a display function like this(sort-of
incomplete code):
Well use a virtual function to return the pointer!
 
B

BWIGLEY

Ian Collins said:
Well use a virtual function to return the pointer!

Is this the only way to do it? it seems a little icky. If it is the
only way would it be better to just set a msg_lin's *p_dsply_obj to
&display on intilization and work off p_dsply_obj?
 
J

Jim Langston

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,297
Messages
2,571,529
Members
48,242
Latest member
BarbMott55

Latest Threads

Top