如何防止具有类类型的 const 变量的默认初始化
我有一个自定义类,我希望它的行为类似于内置类型。
但是我注意到您可以初始化该类的 const 变量而不提供初始值。我的类当前有一个空的默认构造函数。
这是 int 和我的类 foo 的比较:
int a; // Valid
int a = 1; // Valid
const int a = 1; // Valid
const int a; // Error
foo a; // Valid
foo a = 1; // Valid
const foo a = 1; // Valid
const foo a; // Should cause an error, but it compiles
正如你所看到的,我需要阻止
const foo a;
编译。
C++ 专家有什么想法吗?
I have a custom class that I want to behave like a built-in type.
However I have noticed that you can initialise a const variable of that class without providing an initial value. My class currently has an empty default constructor.
Here is a comparison of int and my class foo:
int a; // Valid
int a = 1; // Valid
const int a = 1; // Valid
const int a; // Error
foo a; // Valid
foo a = 1; // Valid
const foo a = 1; // Valid
const foo a; // Should cause an error, but it compiles
As you can see I need to prevent
const foo a;
from compiling.
Any ideas from C++ gurus?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
仅当它具有默认构造函数时才编译,并且它编译是因为它具有默认构造函数,这意味着它已初始化。如果您不想编译该行,只需禁用默认构造函数(也会使
foo a;
成为错误,作为不需要的副作用)。如果没有 foo 的定义或你想要做什么,这就是我所能得到的。我认为没有任何方法可以实现您想要的(即允许默认初始化非常量变量,同时让 const 版本编译失败并允许其他用例 - 需要提供构造函数)
It compiles only if it has a default constructor, and it compiles because it has it, which means that it is initialized. If you don't want that line to compile, just disable the default constructor (will also make
foo a;
an error as an unwanted side effect). Without a definition offoo
or what you want to do, this is as far as I can get.I don't think there is any way of achieving what you want (i.e. allow the non-const variable to be default initialized, while having the const version fail compilation and allowing the other use cases --that require providing constructors)
C++ 的规则简单地说,对于类类型的对象,默认初始化(例如
new T;
)和值初始化(例如new T();
)是相同的,但不适用于基本类型的对象。您无法做任何事情来“覆盖”这种区别。它是语法的基本部分。如果您的类是可值初始化的,那么它也是可默认初始化的。
对于没有任何用户定义的构造函数的类,有一种例外:在这种情况下,成员的初始化是递归完成的(因此,如果您默认初始化该对象,它会尝试默认初始化所有成员),并且这将失败如果任何类成员本身就是基本的,或者同样具有这种性质。
例如,考虑以下两个类:
Foo
的隐式构造函数被拒绝,因为它没有初始化基本成员。然而,y
很高兴地默认初始化,并且ya
和yb
现在“故意留空”。但除非您的类没有任何用户定义的构造函数,否则此信息对您没有帮助。您不能将初始化类型“转发”给成员(例如
)。Foo() : INIT_SAME_AS_SELF(a), b() { }
The rules of C++ simply say that default-initialization (e.g.
new T;
) and value-initialization (e.g.new T();
) are the same for objects of class type, but not for objects of fundamental type.There's nothing you can do to "override" this distinction. It's a fundamental part of the grammar. If your class is value-initializable, then it is also default-initializable.
There is a sort-of exception for classes without any user-defined constructors: In that case, initialization of members is done recursively (so if you default-init the object, it tries to default-init all members), and this will fail if any of the class members are themselves fundamental, or again of this nature.
For example, consider the following two classes:
The implicit constructor for
Foo
is rejected because it doesn't initialize the fundamental members. However,y
is happily default-initialized, andy.a
andy.b
are now "intentionally left blank".But unless your class doesn't have any user-defined constructors, this information won't help you. You cannot "forward" the initialization type to a member (like
).Foo() : INIT_SAME_AS_SELF(a), b() { }