如何防止具有类类型的 const 变量的默认初始化

发布于 2024-12-17 07:53:08 字数 506 浏览 5 评论 0原文

我有一个自定义类,我希望它的行为类似于内置类型。

但是我注意到您可以初始化该类的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

看透却不说透 2024-12-24 07:53:08

仅当它具有默认构造函数时才编译,并且它编译是因为它具有默认构造函数,这意味着它已初始化。如果您不想编译该行,只需禁用默认构造函数(也会使 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 of foo 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)

怀里藏娇 2024-12-24 07:53:08

C++ 的规则简单地说,对于类类型的对象,默认初始化(例如 new T;)和值初始化(例如 new T();)是相同的,但不适用于基本类型的对象。

您无法做任何事情来“覆盖”这种区别。它是语法的基本部分。如果您的类是可值初始化的,那么它也是可默认初始化的。

对于没有任何用户定义的构造函数的类,有一种例外:在这种情况下,成员的初始化是递归完成的(因此,如果您默认初始化该对象,它会尝试默认初始化所有成员),并且这将失败如果任何类成员本身就是基本的,或者同样具有这种性质。

例如,考虑以下两个类:

struct Foo { int a; int b; };
struct Goo { int a; int b; Goo(){} };

//const Foo x; // error
const Goo y;   // OK

Foo 的隐式构造函数被拒绝,因为它没有初始化基本成员。然而,y 很高兴地默认初始化,并且 yayb 现在“故意留空”。

但除非您的类没有任何用户定义的构造函数,否则此信息对您没有帮助。您不能将初始化类型“转发”给成员(例如 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:

struct Foo { int a; int b; };
struct Goo { int a; int b; Goo(){} };

//const Foo x; // error
const Goo y;   // OK

The implicit constructor for Foo is rejected because it doesn't initialize the fundamental members. However, y is happily default-initialized, and y.a and y.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() { }).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文