gpt4 book ai didi

c++ - 为什么继承的 protected operator=() 具有公共(public)访问权限

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

声明为 protected 的重载运算符 = 对于继承父类作为 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

直接使用A是编译不过的。 operator=() 以外的任何其他运算符重载都不会编译。使用 g++ 4.4.7 和 7.3.0 以及 c++98 和 c++17 进行测试。

为什么在这种情况下可以公开访问 operator=()

最佳答案

B 中有一个具有public 访问权限的隐式复制赋值运算符。

来自 the C++11 Standard :

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted ([dcl.fct.def]). The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor. The implicitly-declared copy assignment operator for a class X will have the form

X& X::operator=(const X&)

if

— each direct base class B of X has a copy assignment operator whose parameter is of type const B&, const volatile B& or B, and

— for all the non-static data members of X that are of a class type M (or array thereof), each such class type has a copy assignment operator whose parameter is of type const M&, const volatile M& or M.

Otherwise, the implicitly-declared copy assignment operator will have the form

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;
}

这与 standard says 的内容一致:

The implicitly-defined copy/move assignment operator for a non-union class X performs memberwise copy/move assignment of its subobjects. The direct base classes of X are assigned first, in the order of their declaration in the base-specifier-list, and then the immediate non-static data members of X are assigned, in the order in which they were declared in the class definition.

关于c++ - 为什么继承的 protected operator=() 具有公共(public)访问权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49577963/

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