Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Xgkkp

Class Declaration Oddities

This topic is 5524 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I noticed that I can declare a single class more than once, with different properties. Example: A Header has:
class cTest {
    int addtoa(int a);
}
  
which is called by the main function with a value (say.. 6). In a different source file I re-declare (and define) the class with:
class cTest {
    int addtoa(int a);
    int getadd();
}

int cTest::addtoa(int a)
{
     return a + this->getadd();
}

int cTest::getadd( void )
{
     return 4;
}
  
I notice that when calling from the main function, which only knows about the addtoa function, It still works and Adds 4 to the value (returning 10 when given 4). My Question: Is there any Negative effects to doing this? If not it is very useful because my external functions can use the class (and have the auto-syntax highlighting) while the class can hide it's workings (Up till now I've been using void pointers to devices so not everything needs to know what directx is - this, however is annoying). I can see that to keep classes together i could put the declaration all in one header, but use #ifdef 's to allow different syntax's. [edited by - Xgkkp on June 6, 2003 9:50:59 AM]

Share this post


Link to post
Share on other sites
Advertisement
Visual C++ 6. I was only using Debug exe, I presume it''s the same with release though.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
classes have a vtable which is a bunch of function parameters. thats really not a good way to do that... its way too confusing.

Share this post


Link to post
Share on other sites
only classes with virtual methods have a vtable

*EDIT* Ack... that's no good. You get stack corruption...

Would've been cool

[edited by - daerid on June 4, 2003 9:14:23 PM]

Share this post


Link to post
Share on other sites
errr... so does that mean that it doesn''t work? and why not, because it runs fine???

also, you can let something know a class exists by saying

class cTest;

and then accessing it''s members (even though autocomplete and stuff won''t work). Why is this method any different? I''m confused.

Share this post


Link to post
Share on other sites
The thing is, the header file let''s the source file know the size of the the class. The size is basically the sum of the size of all it''s aggregate members.

The source files will use the size that the definition in the header file gives. Where as the member functions defined in the actual .cpp file used to define the class methods will use a different definition, and thus a different size.

Think of it like this. The address of the object is also the address of it''s first data member. All subsequent data members can be thought of as just offsets from the address of the class.

So, let''s say you declare an instance of the class on the stack, local to a function. Now, that function uses the definition in the header file, which gives it a specific size. If all you do in that header file is define it''s public functions, then sizeof( class ) == 1. So (on most systems) a single byte will be allocated for that object. Now, let''s say you call a member function on that object.

The runtime now jumps to the address of that function, pushing as the first param of that function the this pointer of the class. The function that is being called uses the definition local to the source file that it was declared in, which contains in it the data members of that class. Since all a class is, is a blue-print on how to allocate memory for an object, and it''s different than the one used by the calling function, any member function that utilizes the member variables declared by the local definition of the class (inside the class''s source file), will be accessing data that the calling function has reserved for other uses, since it''s concept of the object is totally different than the member function''s. When the member function changes the data, you get stack corruption. In the case of a heap allocated object, you''ll probably get a "damage after normal block" error, or just a plain access violation error.

The explanation''s a bit complicated, but it shouldn''t be too hard if you think of a class definition as nothing more than a how-to on allocating and accessing memory. This is why all code that uses anything to do with a class''s definition MUST all use the same class definition, which is why they''re defined in header files that can be #included in source files.

Now, if you''re not accessing any member variables in the object, then you won''t have to worry about it. Then again, if that''s the case, you should just make the method static.

Share this post


Link to post
Share on other sites
Since the compiler compiles one source file at a time, it is not aware of (and doesn''t care about) duplicate types in other source files. The linker links the source files together and it uses the names that the compiler gives it. If you have something like the following, you are going to be very sorry:

x1.cpp
    struct Foo
{
... // x1 version of Foo
};
Foo foo1; // foo1 is global

x2.cpp
    struct Foo
{
... // x2 version of Foo which may be different from
// the x1 version
};
extern Foo foo1; // This is really the x1 version of Foo,
// but the compiler doesn''t know about the
// x1 version and assumes it is the x2
// version.


Putting the definition of Foo in a header file and including it in both x1.cpp and x2.cpp will prevent problems like this.

Share this post


Link to post
Share on other sites
Yeah, I know about the size things, but what if it was all declared in the same header file? and things like:

#ifdef DEFINE_FILE
IDirect3DDevice9 *D3DDevice;
#else
void *D3DDevice;
#endif

So It is still the same size, but my source file for the class can use pointers directly instead of having to type cast everything. This way, I can keep all the 3d stuff hidden without having to include all the directX stuff in every file.

[edited by - Xgkkp on June 5, 2003 12:19:44 PM]

Share this post


Link to post
Share on other sites
Whoa, hold up on the size issue.

class class1
{
public:
void add(int a);
int get();
private:
int i;
};

class class2
{
public:
void add(int a);
private:
int i;
};


sizeof(class1) = sizeof(class2), the number of functions doesn''t affect the size of the class. Only the amount of memory stored in it. The memory address of the functions within are not necessarily at an offset of the instantiation of the class. That''s why in OOP there is an extra pointer reference (and it''s why hardcore C proprieters claim that C is faster than C++). There is one memory reference to where class instance is stored, and and the standard memory reference to the functions which are the same for every instantiation.

And I don''t see how this affects the stack either. Aren''t all functions pushed on the stack in the same way? And since by default C++ inlines all member functions (unless "this->" is used since it''s a pointer to a function)?

And Shouldn''t any of these problems be resloved at link time anyway. Say you have one source file that uses one of the class declarations and your main uses the other. When they link to create the exe shouldn''t the compiler see that there are two classes of the same name and resolve any type differences that they might have? Simply it would be like masking the extra functions existence from the rest of the program.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!