Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 仅包含编译时常量的类的大小_C++_Constants - Fatal编程技术网

C++ 仅包含编译时常量的类的大小

C++ 仅包含编译时常量的类的大小,c++,constants,C++,Constants,例如,如果我有一个只包含编译时常量的类 class A { static const int x = 1; static const int y = 2; static const int z = 3; }; 我相信这种情况下,只要不使用常量的地址,它们就可以(将?)在使用它们的编译时被替换,并且不会占用可执行文件中的任何空间(作为常量,也就是说,显然数字本身必须显示)。如果是这样的话,这个类是否也会被优化?而且,如果某个东西继承自类A,但仍然只使用常量本身而不使用它们

例如,如果我有一个只包含编译时常量的类

class A {
    static const int x = 1;
    static const int y = 2;
    static const int z = 3;
};
我相信这种情况下,只要不使用常量的地址,它们就可以(将?)在使用它们的编译时被替换,并且不会占用可执行文件中的任何空间(作为常量,也就是说,显然数字本身必须显示)。如果是这样的话,这个类是否也会被优化?而且,如果某个东西继承自
类A
,但仍然只使用常量本身而不使用它们的地址,这种情况会发生变化吗

哦,假设在非继承版本中,除了作为访问常量的手段之外,类本身实际上没有在任何地方使用


谢谢。

这些变量是否为常量并不重要;它们是静态的,因此它们不会影响类的大小

sizeof(A)
不能为零,因此如果创建
A
的实例,其大小必须至少为一个字节。然而,将
A
作为基类并不一定会增加派生类的大小,因为“基类子对象的大小可能为零”(C++03§1.8/5)。

我认为每种类型的
sizeof
必须至少为1(部分是为了确保该类型的实例在数组中获得不同的地址)

C++0x标准草案第5.3.3节规定:

应用于类时,结果是该类的对象中的字节数,包括将该类型的对象放置在数组中所需的任何填充。最派生类的大小应大于零

它们不应该影响实例的大小(因为它们是静态的),但是它们可能需要存储在可执行文件的某个地方,因为您需要能够在它们上使用操作符的地址。它们是否可以在不存在的情况下进行优化,完全取决于编译器,以及它是否能够判断它们没有被取消引用。枚举可能是在这种特殊情况下使用的更好的工具


但是,一个应用程序中的三个整数不太可能导致问题。

之所以给它一个大小,是因为即使是这样一个类的对象也需要一个大小。(对于初学者来说,如果两个这样的对象是另一个对象的成员,如果您形成指向它们的成员指针,它们会有不同的地址吗?)当这个类被用作基类时,它将受益于空基类优化,并减小为0。其实这个

#include <iostream>

struct A {};
struct B { char x; };
struct C : public A, public B {};

int main()
{
    std::cout << sizeof(A) << '\n';
    std::cout << sizeof(B) << '\n';
    std::cout << sizeof(C) << '\n';
    return 0;
}
#包括
结构A{};
结构B{char x;};
结构C:公共A,公共B{};
int main()
{
std::cout使用的空间
不,静态const int成员将不会为它们分配任何空间,因为它们将作为编译时常量进行计算

至于类对象的大小(即
sizeof(A)
),这是不相关的,除非您正在创建类A的实例,而您明确表示您不相关

改用名称空间?
这就是说,也许你可以使用名称空间来让你的意图更清楚一点?除非你将其用于模板特征之类的东西,否则你似乎在滥用类来完成名称空间所要做的工作。

注意,如果你想要一个地址无法获取的命名整数常量,你可以使用枚举,例如,
enum{x=1};
+1.需要存储在某个地方…如果静态常量成员是编译时常量(9.4.2/4),程序中的任何地方都使用了该常量,则必须在一个翻译单元中定义静态成员常量,才能很好地定义程序。在某个地方是定义它们的翻译单元。“必须在一个翻译单元中定义,才能很好地定义程序”。为什么?如果常量所在的所有位置都使用它作为编译时常量(
literal
),并且没有地址,它们实际上是未使用的,我怀疑是否有任何规则阻止编译器优化它们。命名空间不能用作模板参数。当然,我不知道这是否适用:)确切地说。这可能就是为什么使用类作为模板特征是一种公认的做法,即使使用namespace在这方面可能更符合逻辑。很抱歉,我花了这么长时间才回到这一点,我猜现在已经完全忘记了,但以防万一,我的问题恰恰是这些类是从模板构建的。我有很多类是通过递归模板构建的,只计算一些编译时值,我想知道是否不是他未使用的类仍然会占用空间,尽管它们并没有真正被使用。我应该在问题中明确这一点,但我认为同样的规则会适用,不管是否使用模板,我可能是错的。如果得到任何反馈,我会编辑问题,如果没有,我不会去备份它。是的,同样的规则适用。我尝试在f中回答irst part-const static int成员将不占用任何空间,除非您创建类的实例,否则类的大小无关紧要。AKA:“空基优化“,缩写为EBO,这可能被用作使用私有继承而不是组合的理由。正如我对Suma回复的评论中所述。这些类是从模板创建的,以提供一些编译时常量。我假设同样的规则适用,但现在想知道是否是这样。(和Suma一样,很抱歉花了这么长时间才回复你)我认为对于一个零大小的对象,新的A是一个问题。同样的推理是一个规则,它要求C Maloc返回零大小分配的唯一指针。实际上,这是通过分配至少一个字节来实现的。C++中有类似的规则,它要求类成员有一个不同的成员指针。我认为这是不允许零尺寸物体的主要原因。 1 1 1