调用空类的构造函数实际上会使用任何内存吗?
假设我有一个像这样的类
class Empty{
Empty(int a){ cout << a; }
}
然后我使用它调用它
int main(){
Empty(2);
return 0;
}
这会导致在堆栈上分配任何内存以创建“空”对象吗?显然,参数需要被压入堆栈,但我不想产生任何额外的开销。基本上我使用构造函数作为静态成员。
我想这样做的原因是因为模板。实际的代码看起来
template <int which>
class FuncName{
template <class T>
FuncName(const T &value){
if(which == 1){
// specific behavior
}else if(which == 2){
// other specific behavior
}
}
};
允许我编写类似的代码,
int main(){
int a = 1;
FuncName<1>(a);
}
这样我就可以专门化一个模板参数,而不必指定 T
的类型。另外,我希望编译器能够优化构造函数内的其他分支。如果有人知道这是否属实或如何检查,将不胜感激。我还假设将模板放入这种情况不会改变上面的“空类”问题,对吗?
Suppose I have a class like
class Empty{
Empty(int a){ cout << a; }
}
And then I invoke it using
int main(){
Empty(2);
return 0;
}
Will this cause any memory to be allocated on the stack for the creation of an "Empty" object? Obviously, the arguments need to be pushed onto the stack, but I don't want to incur any extra overhead. Basically I am using the constructor as a static member.
The reason I want to do this is because of templates. The actual code looks like
template <int which>
class FuncName{
template <class T>
FuncName(const T &value){
if(which == 1){
// specific behavior
}else if(which == 2){
// other specific behavior
}
}
};
which allows me to write something like
int main(){
int a = 1;
FuncName<1>(a);
}
so that I get to specialize one template parameter, while not having to specify the type of T
. Also, I am hoping the compiler will optimize the other branches away inside the constructor. If anyone knows if this is true or how to check, that would be greatly appreciated. I assumed also that throwing templates into the situation does not change the "empty class" problem from above, is that right?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
引用Stroustrup:
为什么空类的大小不为零?
确保两个不同对象的地址会不同。出于同样的原因,“new”总是返回指向不同对象的指针。考虑一下:
有一个有趣的规则,规定空基类不需要用单独的字节表示:
这种优化是安全的并且可能是最有用的。它允许程序员使用空类来表示非常简单的概念,而无需任何开销。当前的一些编译器提供了这种“空基类优化”。
Quoting Stroustrup:
Why is the size of an empty class not zero?
To ensure that the addresses of two different objects will be different. For the same reason, "new" always returns pointers to distinct objects. Consider:
There is an interesting rule that says that an empty base class need not be represented by a separate byte:
This optimization is safe and can be most useful. It allows a programmer to use empty classes to represent very simple concepts without overhead. Some current compilers provide this "empty base class optimization".
可能会,也可能不会,视具体情况而定。如果你说:
那么显然事情必须分配。
It might, it might, not, depending on circumstances. If you say:
then obviously things have to be allocated.
尝试一下看看。当要求优化其输出时,许多编译器会消除此类临时对象。
如果反汇编太复杂,则创建两个具有不同数量此类对象的函数,并查看它们周围对象的堆栈位置是否有任何差异,例如:
然后尝试与
empty8
相比运行它创建了八个空的 code> 函数。对于 x86 上的 g++,如果您确实获取任何空值的地址,您将获得堆栈上 x 和 a 之间的位置,因此在输出中包含 x。您不能假设对象的存储最终的顺序与源代码中声明的顺序相同。Try it and see. Many compilers will eliminate such temporary objects when asked to optimise their output.
If the disassembly is too complex, then create two functions with different numbers of such objects and see if there is any difference in the stack locations of objects surrounding them, something like:
and then try running that compared with an
empty8
function with eight Empties created. With g++ on x86, if you do take the address of any of the empties you get a location between x and a on the stack, hence including x in the output. You can't assume that the storage for objects will end up in the same order as they are declared in the source code.