c++0x 中 POD 类型的访问说明符和使用初始值设定项列表之间的关系

发布于 2024-09-10 01:24:36 字数 1514 浏览 3 评论 0原文

采用以下两个类:

class Test1{
 public:
  Test1()=default;
  Test1(char in1,char in2):char1(in1),char2(in2){}
  char char1;
  char char2;
};
class Test2{
 public:
  Test2()=default;
  Test2(char in1,char in2):char1(in1),char2(in2){}
 private:
  char char1;
  char char2;
};

我知道在 c++0x 中,这两个类都被视为 POD 类型,我们可以使用初始化器列表初始化它们的对象,如下所示:

Test1 obj1={'a','b'};//valid in c++0x
Test2 obj2={'a','b'};//valid in c++0x

但我想知道技术原因是什么,当我们在像下面这样的类,不可能使用初始化列表来初始化该类的对象,并且该类不被视为 POD 类型?

class Test{
 public:
  Test()=default;
  Test(char in1,char in2):char1(in1),char2(in2){}
  char char1;
 private:
  char char2;
};
Test obj={'a','b'};//invalid in c++0x

如果您不知道 c++0x 中 POD 的定义:
如果类/结构是简单的、标准布局的,并且它的所有非静态成员都是 POD,则该类/结构被视为 POD。

简单的类或结构定义为:

  1. 具有简单的默认构造函数。这可以使用默认构造函数语法(SomeConstructor() = default;)。
  2. 有一个简单的复制构造函数,它可以使用默认语法。
  3. 有一个简单的复制赋值运算符,它可以使用默认语法。
  4. 有一个简单的析构函数,它不能是虚拟的。

标准布局类或结构定义为:

  1. 仅具有标准布局类型的非静态数据成员
  2. 对所有非静态成员具有相同的访问控制(公共、私有、受保护)
  3. 没有虚函数
  4. 具有没有虚拟基类
  5. 仅具有标准布局类型的基类
  6. 没有与第一个定义的非静态成员类型相同的基类
  7. 没有带有非静态成员的基类,或者没有非静态数据成员在最底层的派生类和至多一个具有非静态成员的基类中。本质上,此类的层次结构中可能只有一个类具有非静态成员。

如果您不知道什么是简单的构造函数或运算符:
编译器会为类生成以下每一项的简单项(如果它不是用户声明的): 复制构造函数、析构函数和复制赋值运算符。
此外,如果类没有用户声明的构造函数,则会为该类生成一个简单的默认构造函数,如果有任何用户声明的构造函数,您可以使用语法(SomeConstructor() = default;) 来制作您自己的简单构造函数默认构造函数。

take two following classes:

class Test1{
 public:
  Test1()=default;
  Test1(char in1,char in2):char1(in1),char2(in2){}
  char char1;
  char char2;
};
class Test2{
 public:
  Test2()=default;
  Test2(char in1,char in2):char1(in1),char2(in2){}
 private:
  char char1;
  char char2;
};

I know in c++0x both of these classes are considered as POD types and we can initialize objects of them using initializer lists as below:

Test1 obj1={'a','b'};//valid in c++0x
Test2 obj2={'a','b'};//valid in c++0x

But I wonder what the technical reason is that when we have different access specifiers in a class like below, it's not possible to use initializer list for initializing objects of that class and that class is not considered as a POD type ?

class Test{
 public:
  Test()=default;
  Test(char in1,char in2):char1(in1),char2(in2){}
  char char1;
 private:
  char char2;
};
Test obj={'a','b'};//invalid in c++0x

In case you don't know definition of PODs in c++0x:
A class/struct is considered a POD if it is trivial, standard-layout, and if all of its non-static members are PODs.

A trivial class or struct is defined as one that:

  1. Has a trivial default constructor. This may use the default constructor syntax (SomeConstructor() = default;).
  2. Has a trivial copy constructor, which may use the default syntax.
  3. Has a trivial copy assignment operator, which may use the default syntax.
  4. Has a trivial destructor, which must not be virtual.

A standard-layout class or struct is defined as one that:

  1. Has only non-static data members that are of standard-layout type
  2. Has the same access control (public, private, protected) for all non-static members
  3. Has no virtual functions
  4. Has no virtual base classes
  5. Has only base classes that are of standard-layout type
  6. Has no base classes of the same type as the first defined non-static member
  7. Either has no base classes with non-static members, or has no non-static data members in the most derived class and at most one base class with non-static members. In essence, there may be only one class in this class's hierarchy that has non-static members.

In case you don't know what a trivial constructor or operator is:
Compiler generates a trivial one of each of following items for a class, in case it isn't user-declared:
Copy constructor, destructor and copy assignment operator.
And also if there's no user-declared constructor for a class, a trivial default constructor is generated for that class, in case there are any user-declared constructors you can use the syntax(SomeConstructor() = default;) to make your own trivial default constructor.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

oО清风挽发oО 2024-09-17 01:24:36

“技术”原因如下:

分配具有相同访问控制的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址。具有不同访问控制的非静态数据成员的分配顺序未指定(C++0x §9.2/12)。

只要所有非静态数据成员具有相同的访问控制,它们的顺序就可以明确指定;否则他们的顺序是未指定的。

The "technical" reason is due to the following:

Nonstatic data members of a (non-union) class with the same access control are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (C++0x §9.2/12).

So long as all the nonstatic data members have the same access control, their order is well-specified; otherwise their order is unspecified.

倾`听者〃 2024-09-17 01:24:36
class Test{
 public:
  Test()=default;
  Test(char in1,char in2):char1(in1),char2(in2){}
  char char1;
 private:
  char char2;
};

考虑到上述类以下语法在 c++0x 中有效:

Test obj={'a','b'};//valid in c++0x

最终提案是 此处

class Test{
 public:
  Test()=default;
  Test(char in1,char in2):char1(in1),char2(in2){}
  char char1;
 private:
  char char2;
};

considering above class following syntax is valid in c++0x:

Test obj={'a','b'};//valid in c++0x

The final proposal is here.

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