在值类型的C#结构中,值类型可以实现接口的所有优点而不会增加大小,请查看以下代码段:

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"
    }
}


但是,当我尝试在C ++中实现此功能时,结构的大小会变大:

#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"
}


我认为这是由于指向虚拟方法表的指针。是否可以在不增加对象大小的情况下实现类似的功能?

最佳答案

如果您确实不希望存储额外的v-table指针的开销,则可以始终在将点作为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; }
};


用法示例:

Point point = {0};
MovablePoint movablePoint(point);
doSomething(movablePoint);


现在,当您需要持久保存v-table时,就不必再存储它了。

关于c# - 防止在C++中创建虚拟方法表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28932728/

10-11 22:44
查看更多