sizeof() giving strange results...

Started by
27 comments, last by SiCrane 11 years, 2 months ago
i wrote a 3d vector class a while ago, been using it ever since without problem, now recently i found out it seems to have the wrong size in bytes

class Vector3 {
public:
    float x;
    float y;
    float z;
    Vector3();
    Vector3(const Vector3 &v);
    Vector3(float xIn, float yIn, float zIn);
    virtual Vector3 operator=(const Vector3 &rhs);
     ...
};
this yields a sizeof() of 16 bytes instead of 12.
by trying around, i found out that it is due to the the operator(s) being virtual (or any virtual method i add, even the destructor)
if i leave out the 'virtual' keyword, the size is correct, but the linker cant resolve the symbols.

any idea how to handle this, or why the use of 'virtual' changes a classes size?

also, pls dont link descriptions to the virtual keyword, i have been through many, and still don't get it =)
thanks in advance,
Tasche
Advertisement
The class gets bigger because of a pointer to the vtable. That said, there shouldn't be any reason that a vector class should have any virtual functions in it. Inheriting from a 3D vector is a somewhat bizarre option.

Virtual is for inheritance purposes - your class isn't inheriting, and likely shouldn't be inherited from, so none of the functions should be virtual.

operator= is supposed to return a reference: "Vector3 &operator=(const Vector3 &rhs);"

What does your function declaration look like? Your linker errors may be related to that. Could you post the error message?

Also, if you don't provide a copy constructor or an operator=, the compiler will make some for you that will work just fine.
operator= is supposed to return a reference: "Vector3 &operator=(const Vector3 &rhs);"

This is just convention, nowhere does the standard mandate that an copy assignment operator shall have any particular return type, it could even return void. The only requirement is that it shall have exactly one parameter as per C++11 13.5.3/1. 13.5.3/2 has an example with an copy assignment operator returning an int by value, for example.

As Álvaro mentions, if you do not declare a copy assignment operator, one will be implicitly declared and synthesised for you that does an element-wise assignment of the members.

To make it is hell. To fail is divine.

This is just convention [...]
Conventions are important. The standard lets you have an operator + that modifies its operands, overload operator comma (,) and many other horrible things that will confuse the hell out of anybody reading your code. Trying to minimize surprises for anyone reading your code is a very good thing to do, and returning a reference from operator= goes well with that philosophy.
Truth. Just because you can, doesn't mean you should.

Returning a mutable reference allows lots of nice things, such as chained assignments, and shorthand such as:
(flatVector = vector3d).z = 0.0f;

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Truth. Just because you can, doesn't mean you should.

Returning a mutable reference allows lots of nice things, such as chained assignments, and shorthand such as:
(flatVector = vector3d).z = 0.0f;



I would fire you for that code.

Then I would set you on fire for that code.

Then I would launch a whole army of bots against you to burn those remaining bits of you that were left for that code.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.


operator= is supposed to return a reference: "Vector3 &operator=(const Vector3 &rhs);"


This is just convention, nowhere does the standard mandate that an copy assignment operator shall have any particular return type, it could even return void. The only requirement is that it shall have exactly one parameter as per C++11 13.5.3/1. 13.5.3/2 has an example with an copy assignment operator returning an int by value, for example.


Well, if you think about it, it doesn't make a lot of sense to have a copy operator return a copy rather than a reference. Sure, you could return an int, or a pointer, or even nothing at all (void). But to return a copy, you would need to invoke the copy operator, which invokes the copy operator, which... well, maybe you get my point.

I imagine the OP's problem is that the compiler can't find the definition for the copy assignment operator during the definition of the copy assignment operator, because it hasn't been defined yet. I think SotL's answer is the best so far.

Stephen M. Webb
Professional Free Software Developer

But to return a copy, you would need to invoke the copy operator, which invokes the copy operator, which... well, maybe you get my point.
Different copy mechanism. Returning by copy would invoke the copy constructor, not the assignment operator.

This topic is closed to new replies.

Advertisement