gpt4 book ai didi

c++ - MSVC9.0 bug 或对虚拟继承的误解和 friend ?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:57:51 25 4
gpt4 key购买 nike

考虑以下代码:

class A
{
friend class B;
friend class C;
};

class B: virtual private A
{
};

class C: private B
{
};

int main()
{
C x; //OK default constructor generated by compiler
C y = x; //compiler error: copy-constructor unavailable in C
y = x; //compiler error: assignment operator unavailable in C
}

MSVC9.0(Visual Studio 2008 的 C++ 编译器)确实会生成默认构造函数,但无法为 C 生成复制和赋值运算符,尽管 C 是 A 的友元。这是预期的行为还是 Microsoft漏洞?我认为是后者,如果我是对的,任何人都可以指出一篇文章/论坛/...讨论这个问题或微软对这个错误使用react的地方。提前谢谢你。

附言顺便说一句,如果将两个私有(private)继承都更改为 protected ,则一切正常

附言我需要证明,上面的代码是合法的还是非法的。据我了解,确实有意无法从中派生具有虚拟私有(private)基的类。但他们似乎错过了 friend 的部分。所以...开始吧,我的第一个赏金:)

最佳答案

按照我解释标准的方式,示例代码格式正确。 (是的,friend 声明与@Steve Townsend 引用的内容有很大不同。)

11.2p1: If a class is declared to be a base class for another class using the private access specifier, the public and protected members of the base class are accessible as private members of the derived class.

11.2p4: A member m is accessible when named in class N if

  • m 作为 N 的成员是公开的,或者
  • m 作为N 的成员是私有(private)的,引用发生在类N 的成员或友元中,或者
  • m 作为N 的成员受到保护,引用发生在类N 的成员或友元中,或者在成员中或从 N 派生的类 P 的 friend ,其中 m 作为 P 的成员是私有(private)的或 protected ,或
  • 存在 N 的基类 B 可在引用点访问,并且 m 在类中命名时可访问 < em>B.

11.4p1: A friend of a class is a function or class that is not a member of the class but is permitted to use the private and protected member names from the class.

第 11 条(成员访问控制)中没有任何语句暗示某个类的 friend 的访问权限永远少于与其成为 friend 的类。请注意,“可访问”仅在特定类的上下文中定义。尽管我们有时会笼统地谈论一个成员或基类是“可访问的”或“不可访问的”,但更准确的说法是它是“在所有上下文中都可访问”还是“在所有类中都可访问”(如当仅使用 public 时)。

现在介绍在自动定义的方法中检查访问控制的部分。

12.1p7: An implicitly-declared default constructor for a class is implicitly defined when it is used to create an object of its class type (1.8). The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with an empty mem-initializer-list (12.6.2) and an empty function body. If that user-written default constructor would be ill-formed, the program is ill-formed.

12.6.2p6: All sub-objects representing virtual base classes are initialized by the constructor of the most derived class (1.8). If the constructor of the most derived class does not specify a mem-initializer for a virtual base class V, then V's default constructor is called to initialize the virtual base class subobject. If V does not have an accessible default constructor, the initialization is ill-formed.

12.4p5: An implicitly-declared destructor is implicitly defined when it is used to destroy an object of its class type (3.7). A program is ill-formed if the class for which a destructor is implicitly defined has:

  • 具有不可访问的析构函数的类类型(或其数组)的非静态数据成员,或
  • 具有不可访问的析构函数的基类。

12.8p7: An implicitly-declared copy constructor is implicitly defined if it is used to initialize an object of its class type from a copy of an object of its class type or of a class type derived from its class type. [Note: the copy constructor is implicitly defined even if the implementation elided its use (12.2).] A program is ill-formed if the class for which a copy constructor is implicitly defined has:

  • 具有不可访问或不明确的复制构造函数的类类型(或其数组)的非静态数据成员,或
  • 具有不可访问或不明确的复制构造函数的基类。

12.8p12: A program is ill-formed if the class for which a copy assignment operator is implicitly defined has:

  • const 类型的非静态数据成员,或者
  • 引用类型的非静态数据成员,或者
  • 具有不可访问的复制赋值运算符的类类型(或其数组)的非静态数据成员,或
  • 具有不可访问的复制赋值运算符的基类。

所有这些提及“不可访问”或“可访问”的要求都必须在某个类的上下文中进行解释,并且唯一有意义的类是隐式定义了成员函数的类。

在原始示例中,class A 隐式具有 public 默认构造函数、析构函数、复制构造函数和复制赋值运算符。到 11.2p4,由于 class Cclass A 的友元,所有这些成员在 C 类中命名时都可以访问。因此,对 class A 的那些成员的访问检查不会导致 class C 的默认构造函数、析构函数、复制构造函数或复制赋值运算符的隐式定义出错-形成。

关于c++ - MSVC9.0 bug 或对虚拟继承的误解和 friend ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3900192/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com