View Full Version: question about using classes

C++ Learning Community > C++ in General > question about using classes


Title: question about using classes
Description: like um.. hard to explain in one line :P


ih8censorship - May 15, 2004 03:15 PM (GMT)
allright lets see if i can explain this. say i have a class for all the often used functions of my program. and a lot of the data and other function calls in these member functions should really change depending on the particular program , but it would be possible to just put it in the 'main' program function. so i guess what im getting at is it proper to change the contents of a couple member functions of a class very often, or just write it into the 'main' function?

hope someone can make sense of this.....

C-Man - May 15, 2004 04:01 PM (GMT)
hmmmm ...... :mellow: not quite sure what are you trying to ask here :blink:

Steille - May 16, 2004 08:39 PM (GMT)
I think youare saying this...

"Should I alter members functions of a class to fit my program, or recreate those functions that need modifying in the main function?"

Generally, I leave ancestor code alone, if I need to make a significant change, I bring it to the current level Im coding on and make the changes, then just never call the ancestor.

Ive had to do that in my regular language here and there. However, Im working with other people that may also call the ancestor code, so thats my major reasoning for doing so.

If thats not what youre asking, then Im lost.

- Steille :cool:

dr voodoo - May 16, 2004 08:56 PM (GMT)
QUOTE
allright lets see if i can explain this. say i have a class for all the often used functions of my program. and a lot of the data and other function calls in these member functions should really change depending on the particular program , but it would be possible to just put it in the 'main' program function. so i guess what im getting at is it proper to change the contents of a couple member functions of a class very often, or just write it into the 'main' function?

hope someone can make sense of this.....

I assume you mean something like:
CODE
class A{
 friend int main();
 int a;
 int b;
public:
 //...
};
int main(){
 A a;
 a.a=8;
 a.b=50;
 return 0;
}

If so you are violating the open close principe. Once a class is defined it should not be changed only expanded using inheritance. If you come to a situation where you feel the need for this then most of the time you have thrown several class into a big one or you aren't using templates when you need them. Descibe your situation and we may be able to help you.

ih8censorship - May 16, 2004 09:05 PM (GMT)
yeah i think its what Steille says-- im making a screensaver class theres 2 member functions that a programmer would more than likely want to modify- the function containing graphics stuff, and the function containing the dialog/window for the configureation box. other than that, theres really not any reason to modify any of the other class members because they should be the same for all screensavers. so ya think i should just have the 2 member functions that are most likely to be modifyed be written by the programmer? now that i think about it it would be a lot more convineient for ME to do it that way, but i guess what im getting at is that "proper" programming? i like to do things right if i can :)

dr voodoo - May 16, 2004 09:15 PM (GMT)
Use inheritance:
CODE
class ScreenSaver{
 //...
public:
 ScreenSaver(int){}
 //...
 virtual void draw(HDC){
 }
 virtual void configure(){
   MessageBox(0,"No configuration for this screen saver","Sorry",MB_OK);
 }
};
class MyScreenSaver:public ScreenSaver{
public:
 MyScreenSaver(int n):
   ScreenSaver(n){
 }
 void draw(HDC hdc){
   //do stuff
 }
};
int main(){
 MyScreenSaver ssaver(5);
 return 0;
}

By default the function in the parent class is used, but if a function is declared in the derived class then it is used.

ih8censorship - May 16, 2004 09:28 PM (GMT)
allright i think i understand the stuff there exept what does "virtual" do, and how exactly does it know to use the default function or the user specifyed one?

hmm i really should research more on inheritance i guess

**edit** ive done some research on inheritance and it looks like its even better than i need! :D that will allow users of the base class to really expand also. i still wonder though whats the "virtual" do?

myork - May 17, 2004 12:28 PM (GMT)
Virtual: When applied to methods, means use the highest version of the method you can.

CODE

#include <iostream>
#include <vector>

class A
{
   public:  int doWork() {std::cout << "Doing A\n";}
};

class B: public A
{
   public:  int doWork() {std::cout << "Doing B\n";}
};

class C: public B
{
   public:  int doWork() {std::cout << "Doing C\n";}
};

int main(int argc,char*argv[])
{
 A    a;
 B    b;
 C    c;

 a.doWork();
 b.doWork();
 c.doWork();

/*
*  This will do what you expect and print A B C on the output.
*  But what happens when you want to hold all the objects in a generic container.
*/

 std::vector<A*>    vecOfA;

 vecOfA.push_back(&a);
 vecOfA.push_back(&b);
 vecOfA.push_back(&c);

 for(std::vector<A*>::iterator loop=vecOfA.begin();loop != vecOfA.end();loop++)
 {
     loop->doWork()
 }

/*
*  Most beginners would have expected that to print out A B C again.
*  but it does not it will print out A A A.
*
*  Why?
*  That's because everything is stored as a pointer to an A object.
*  To make it use the top most version of the function you need to declare the
*  function 'virtual'.
*  This tells the compiler that the function may be overriden by a more important version
*  and it need to find the most dignificant version. So it will look up the inheritance chain
*  looking for the most significant version for that particular object.
*
*  Try adding virtual to the doWork() method and see what happens.
*/
 return(0);
}

Nova - May 17, 2004 03:16 PM (GMT)
Sorry this isn't my topic, but what does "->" mean? I have never been able to find out. The same operator is used in php and perl and out of 3 books, it never explained what it was for. <_<

myork - May 17, 2004 03:20 PM (GMT)
QUOTE
Sorry this isn't my topic, but what does "->" mean?



It used to access the members of an object when you access the object via a pointer.

Example.

CODE

class A
{
   public:   int value;
};

A    a;
A*   b = &a;

a.value   = 15;
b->value  = 25;  // b is a pointer so we need to use '->' to dereference the access to an internal member.


dr voodoo - May 17, 2004 05:03 PM (GMT)
QUOTE
allright i think i understand the stuff there exept what does "virtual" do, and how exactly does it know to use the default function or the user specifyed one?

hmm i really should research more on inheritance i guess

**edit** ive done some research on inheritance and it looks like its even better than i need!  that will allow users of the base class to really expand also. i still wonder though whats the "virtual" do?

What often helps me understanding such lanuage constructions is the see how it is implemented. Here's a C++ version and C version of the same code:
CODE
class A{
 int a;
public:
 virtual void foo(){};
 virtual void foo2(int){};
 void foo3(){};
};
class B:public A{
 int b;
public:
 void foo();
 void foo2(int);
 int foo4();
};
//...
B b;
A&a=b;//upcast
a.foo();

CODE
//A's VTable
struct VTable_A{
 void(*foo)();
 void(*foo2)(int);
};
//The struct of A
struct A{
 VTable_A*vtable;
 int a;
}
//A's member fucntions
void A_foo(A*this){}
void A_foo2(A*this,int){}
void foo3(A*this){}
//creation of A's vtable
VTable_A vtable_a={A_foo,A_foo2};

//B's VTable
struct VTable_B{
 void(*foo)();
 void(*foo2)(int);
 int(*foo4)();
};
//The struct of B
struct B{
 VTable_B*vtable;
 int a;
 int b;
}
//B's member fucntions
void B_foo(B*this){}
void B_foo2(B*this,int){}
int B_foo4(B*this){}
//creation of B's vtable
VTable_B vtable_b={B_foo,B_foo2,B_foo4};

//...
B b;
b.vtable=&vtable_b;

A*a=(A*)&b;

(*a->vtable.foo)(a);

The trick is that A's member function are not called direckty but by dereferencing the function pointer in the vtable. This vtable is unique for each type and is not changed when upcasting. When upcasting from B to A the object still points to B's vtable and therefor dereferences the function pointers in B's vtable calling B's member functions.

Such a lookup in the vtable is done if the function is declared virtual. A vtable is only generated if there is at least 1 virtual function. Often virtual destructors are a good idea.

The vtable can also be used for downcating with dynamic_cast

Note that the C++ standard does not requier the implementation over the vtable but nearly all compilers do it this way.




* Hosted for free by InvisionFree