Reputation:
In C# structures being value types may implement interfaces with all its benefits without size overhead, look at this snippet:
interface IMove
{
void Move(Int32 l);
}
struct Point : IMove
{
public Int32 x;
public Int32 y;
public void Move(Int32 l)
{
this.x += l;
this.y += l;
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Marshal.SizeOf(typeof(Int32))); // Prints "4"
Console.WriteLine(Marshal.SizeOf(typeof(Point))); // Prints "8"
}
}
But when I try to implement this in C++ the size of the structure becomes larger:
#include <iostream>
class IMove
{
public:
virtual void move(int l) = 0;
};
class Point : public IMove
{
public:
int x;
int y;
void move(int l)
{
this->x += l;
this->y += l;
}
};
int main()
{
std::cout << sizeof(int) << "\n"; // Prints "4"
std::cout << sizeof(Point) << "\n"; // Prints "12"
}
I think it's because of the pointer to the virtual method table. Is it possible to implement similar functionality without overhead in object size?
Upvotes: 0
Views: 79
Reputation: 20130
There is Curiously Recurring Template Pattern to separate interface and implementation, no vtable needed
template <typename ToMove> struct Moveable
{
void move()
{
static_cast<ToMove*>(this)->move_implementation();
}
};
struct Point : Moveable<Point>
{
void move_implementation()
{
cout << "Moving...\n";
}
};
Upvotes: 1
Reputation: 3226
If you really don't want the overhead of storing the extra v-table pointer, you can always use a wrapper object before passing the point as an IMove:
struct Point { int x; int y; };
struct MoveablePoint : public IMove {
Point& point;
MovablePoint(Point& point) : point(point) {}
virtual void move(int l) { point.x += l; point.y += l; }
};
Example usage:
Point point = {0};
MovablePoint movablePoint(point);
doSomething(movablePoint);
Now there's no need to store the v-table in point when you need it to persist.
Upvotes: 1