GCC可以将类编译为结构体吗?
Can GCC compile classes to work as structs?
是否有办法强制编译器(特别是GCC)使类编译为面向对象的C?具体来说,我想要实现的是这样写:
class Foo {
public:
float x, y, z;
float bar();
int other();
...etc
};
Foo f;
float result = f.bar()
int obSize = sizeof(Foo);
却编译成完全相同的:
Struct Foo { float x, y, z; };
float Foo_bar(Foo *this);
Foo f;
float result = Foo_bar(&f);
int obSize = sizeof(Foo);
我的动机是提高可读性,但又不为Foo的每个对象遭受内存损失。我想类的实现通常是obSize为
obSize = sizeof(float)*3 + sizeof(void*)*number_of_class_methods
在内存受限的微控制器中主要使用c++类。然而,我想如果我让它工作,我也会用它来进行网络序列化(当然是在相同的端序机器上)。
你的编译器实际上为你做了这些。它甚至可以通过将this
指针放在寄存器中而不是将其压入堆栈来优化(这至少是MSVC在Windows上所做的),这在标准的C调用约定中是无法做到的。
:
obSize = sizeof(float)*3 + sizeof(void*)*number_of_class_methods
- 这是完全错误的。你试过吗?
- 即使有虚函数,每个对象也只能添加一个指向函数表的指针(每个类一个表)。在没有虚函数的情况下,除了对象的成员之外,不会向对象添加任何内容(也不会生成函数表)。
-
void*
表示指向数据的指针,而不是指向代码的指针(它们不需要具有相同的大小) - 不能保证等效C结构体的大小为
3 * sizeof(float)
。
c++已经为你所说的非多态类(没有虚方法的类)做了。
一般来说,c++类将具有与C结构体相同的大小,除非该类包含一个或多个虚方法,在这种情况下,开销将是每个类实例的单个指针(通常称为vptr)。
还将有一个'vtbl'的单个实例,该实例具有每个虚函数的一组指针-但是该vtbl将在所有该类类型的对象之间共享。例如,每个类类型都有一个VTBL,并且该类对象的各种VPTRS将指向同一个VTBL实例)。
总而言之,如果你的类没有虚方法,它将不会大于相同的C结构体。这符合c++不为不用的东西买单的理念。但是,请注意,c++类中的非静态成员函数确实接受参数列表中没有明确提到的额外参数(this
指针)-这实际上是您在问题中讨论的内容。
脚注:在c++中,类和结构是一样的,除了默认成员的可访问性有一点不同。在上面的答案中,当我使用术语"类"时,这种行为同样适用于c++中的结构体。当我使用术语"结构"时,我指的是C结构体。
还要注意,如果你的类使用继承,继承的"开销"取决于继承的确切种类。但是就像多态类和非多态类之间的区别一样,无论成本是多少,它只有在你使用它时才会带来。
不,你的想象错了。类方法在对象中不占用任何空间。为什么不写一个类,然后取sizeof。然后添加更多的方法并再次打印sizeof。你会发现它没有改变。像这样
的第一个程序
class X
{
public:
int y;
void method1() {}
};
int main()
{
cout << sizeof(X) << 'n'; // prints 4
}
第二个程序
class X
{
public:
int y;
void method1() {}
void method2() {}
void method3() {}
void method4() {}
void method5() {}
void method6() {}
};
int main()
{
cout << sizeof(X) << 'n'; // also prints 4
}
实际上,我认为使用类没有特定的内存损失,因为成员函数为类的每个实例存储一次。因此,您的内存占用将更像1*sizeof(void*)*number_of_class_methods + N*sizeof(float)*3
,其中您有Foo
的N
实例。
只有在使用虚函数时才会受到额外的惩罚,在这种情况下,每个对象都携带一个指向虚函数表的指针。
你需要测试,但据我所知,一个类实例做只有存储指针到它的方法,如果说的方法是虚拟的;否则,一个结构和一个类将占用大致相同的内存量(除了不同的编译器所做的不同对齐等)。
- 根据用户回答声明"Players"。用户选择玩家数量。播放器是结构体
- 结构体 S { int align; } 之间的区别;(struct 关键字后的名称)和 struct { int al
- C++ - 如何在结构向量中找到结构体一个成员的最大值?
- 包含 std::list 的结构体的 C++ 初始化
- 结构体和类的不同大小(),彼此具有相同的字段类型
- 如何使用结构体的向量数组?
- 如何使用结构体在C++中更改这些代码?
- 无法在 Mosquitto MQTT Broker 插件上访问结构体 mosquitto 的元素
- 我应该如何在C++中使用结构体解决输入失败的问题?
- Qsort() 比较结构体整数的总和
- 如何使用迭代器指向结构体c++的向量
- 在C++中使用链表的堆栈实现中,访问结构体headNode成员count和top会导致运行时错误
- 如何获取结构体成员的地址
- 创建结构体向量,表达式:向量下标超出范围
- boost::任何带有结构体和无符号整数
- 如何在构造函数中初始化结构体的动态数组?
- 如何在编译时输出结构体中成员的偏移量(C/ c++)
- 结构体中的枚举编译错误
- 是否有一个编译时函数/宏来确定c++ 0x结构体是否为POD
- GCC可以将类编译为结构体吗?