为什么继承的受保护操作员=()有公共访问权限
Why does inherited protected operator=() has public access
被称为"保护为受保护"的超载运算符=
可以公开访问子类,将父级继承为public。
#include <iostream>
class A {
public:
A(char c) : i(c) {}
char i;
protected:
A& operator=(const A& rdm) {
std::cout << "accessing operator=()" << std::endl;
i = 'x';
return *this;
}
};
class B : public A {
public:
B(char c) : A(c) {}
};
int main(int ac, char** av) {
B a('a');
B b('b');
std::cout << "a.i == " << a.i << std::endl;
a = b;
std::cout << "a.i == "<< a.i << std::endl;
}
编译时没有错误:
$ g++ -Wall -o test_operator ~/test_operator.cpp
$ ./test_operator
a.i == a
accessing operator=()
a.i == x
使用直接无法编译的。除operator=()
以外的任何其他操作员过载不会编译。用G 4.4.7和7.3.0测试C 98和C 17。
为什么在这种情况下可以公开访问operator=()
?
B
中有一个隐式副本分配运算符。
来自C 11标准:
如果类定义未明确声明副本分配运算符,则隐含地声明。如果类定义声明移动构造函数或移动分配运算符,则将隐式声明的副本分配运算符定义为已删除;否则,将其定义为默认设置([DCL.FCT.DEF](。如果类有用户指定的复制构造函数或用户指定的破坏者,则将后一种情况弃用。X类的隐式副本分配运算符将具有表格
X& X::operator=(const X&)
如果
-
X
的每个直接基类B
都有一个复制分配操作员,其参数为类型const B&
,const volatile B&
或B
,以及- 对于
X
的所有非静态数据成员,属于类型M
(或其数组(,每个类型类型都有一个复制分配运算符,其参数为const M&
,const volatile M&
或 CC_14或M
。否则,隐式宣布的副本分配运算符将具有表单
X& X::operator=(X&)
换句话说,您的代码表现得好像您有:
class B : public A {
public:
B(char c) : A(c) {}
B& operator=(B const& rhs) { A::operator==(rhs); return *this; }
};
这是您的更新版本,它演示了隐式声明的复制分配运算符函数的行为。它证明了B
不继承A
的复制分配操作员。
#include <iostream>
class A {
public:
A(char c) : i(c) {}
char i;
protected:
A& operator=(const A& rdm) {
std::cout << "accessing A::operator=()" << std::endl;
i = 'x';
return *this;
}
};
class X
{
public:
X& operator=(X const& rhs)
{
std::cout << "accessing X::operator=()" << std::endl;
return *this;
}
};
class B : public A {
public:
B(char c) : A(c) {}
X x;
};
int main(int ac, char** av) {
B a('a');
B b('b');
std::cout << "a.i == " << a.i << std::endl;
a = b;
std::cout << "a.i == "<< a.i << std::endl;
}
输出:
a.i == a
accessing A::operator=()
accessing X::operator=()
a.i == x
隐式声明/定义的复制分配运算符的行为就像我们有:
B& operator=(B const& rhs)
{
A::operator==(rhs);
this.x = rhs.x;
return *this;
}
这与标准所说的一致:
非工会类
X
隐式定义的副本/移动分配操作员执行其子对象的成员复制/移动分配。X
的直接基础类是在 base-Specifier-list 中以其声明的顺序分配的,然后分配了X
的直接非静态数据成员它们在班级定义中被声明。
- 编写一个函数来删除单链表中的节点(尾部除外),仅授予对该节点的访问权限
- 为什么我在空指针错误(链表)中获取成员访问权限
- 为什么"delete"操作员给我访问权限冲突
- 父级的子属性 - 访问权限
- 从C++获得对在python中创建的C++类的访问权限
- 威纳派读取自定义文件或文件夹的所有访问权限
- 授予另一个类对特定方法的访问权限
- 链接 boost 库时"Error while loading shared libraries"引发的,除了我无法使用 root 访问权限来修复它
- 正确的友元定义,以授予 std::map 对私有默认构造函数的访问权限
- TOCTTOU - 在处理文件之前使用访问权限
- 如何通过指针仅向结构的某些成员提供可变访问权限
- main() 对连续运行的线程中的编辑值具有只读访问权限 - C++
- 如何使用 c++ 创建对"everyone"具有共享访问权限的文件夹
- 嵌套类嵌套类的访问权限
- 为什么继承的受保护操作员=()有公共访问权限
- 根据线程优先级/特权授予对资源的访问权限
- 如何在不需要 root 访问权限的情况下为应用程序中的线程设置相对线程优先级
- 来自模板参数的派生类没有受保护的成员访问权限
- 在没有朋友的情况下向私有构造函数授予访问权限
- 仅授予对具有相同基类的类的函数访问权限