使用"using"声明隐藏基类方法不适用于赋值运算符
Hiding base class method with "using" declaration doesn't work for assignment operator
下面是派生类中如何使用基本方法的简单示例:
struct Base {
void foo ();
Base& operator = (const Base&);
};
struct Derived : Base {
// ...
};
int main () {
Derived d1, d2;
d1.foo(); // calls Base::foo
d1 = d2; // calls Base::operator =
}
如果我在Derived
的主体中添加以下语句来隐藏这两个方法。。。
struct Derived : Base {
//...
private: // hide the below method for `Derived` objects
using Base::foo;
using Base::operator =;
}
则成功地隐藏(变得不可访问)CCD_ 2
但Base::operator =
仍然可访问!!
d1.foo(); // error
d1 = d2; // ok !!
其他运营商也出现了同样的现象。这是一个g++的演示。
可访问性规则(由于using
关键字而应用)不应该以同样的方式应用于方法和运算符吗
如果不是,那么语句using operator =;
的意义是什么?它只是被编译器忽略了吗?
更新:
- 我的第一个想法是,编译器可能正在生成自己的默认CCD_ 6。这是错误的,因为它使用
Base::operator =
- 如果我使用
private
继承,那么Base::foo()
将自动隐藏(即使没有using
)。但对CCD_ 11无影响,它仍然有效
请注意,我不想要"如何隐藏它"的解决方案。但我想从语言的角度来理解,为什么运算符不像其他方法那样隐藏。
编译器将为Derived类生成一个默认的operator=
,而这个隐含的Derived::operator=
又在内部调用Base::operator=
为了消除这种情况,我们需要明确禁用operator=
:
struct Derived : Base {
private: Derived& operator = (const Derived&); // C++03 way
};
struct Derived : Base {
Derived& operator = (const Derived&) = delete; // C++11 way
};
更新:
我的第一个想法是,编译器可能会生成自己的默认派生::运算符=。这是错误的,因为它使用Base::operator =
。其他运营商也是如此。如果我使用私有继承,那么
Base::foo()
会自动隐藏(即使不使用)。但对Base::operator =
没有影响,它仍然有效。
你的第一个想法是正确的。您没有声明复制赋值运算符,因此为您隐式声明了一个。然后odr-使用隐式声明的复制赋值运算符,因此编译器提供了隐式定义的复制赋值操作符。结构或类的隐式定义的复制赋值运算符执行该类基类的成员式复制赋值,然后执行该类的非静态数据成员。
隐式定义的复制赋值运算符是类成员。通过using
或私有继承向外部世界隐藏基类复制构造函数一点也不重要,因为该基类赋值运算符对这个隐式定义的复制赋值运算符可见。
- FLTK 2.0构建和演示,适用于VS2019的2011年左右的代码库
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 为什么这适用于 G++ 而不是 CLANG?
- 为什么不区分大小写适用于 std::unordered_set的 std::hash 函数?
- 声明适用于 auto,但不能显式声明类型?
- 什么是通用运行时组件 #ifdef 适用于Windows(UWP)而不是iOS
- Windows 上的 Cmake 不添加共享库路径(适用于 linux)
- Typedef适用于结构,但不适用于枚举,仅适用于C++
- 为什么函数模板不理解 NULL,但适用于 nullptr
- 链接器读取库,但在其中找不到符号?未解析的外部符号,但仅适用于 Win32 而不是 x64
- Netbeans 8.1(适用于 C/C++)找不到我的编译器(gcc-6.0.0 开发版本)
- random_shuffle() 适用于 Windows,但不能在 Linux 上编译
- C++指针到方法模板推导在面向 x86 时不编译,但适用于 x64
- 不在异常中嵌入std::字符串的规则是否仍然适用于move构造函数
- 移动文件夹Windows c++:适用于Vista及以上版本,不包括XP
- 适用于Android的Qt找不到任何兼容的设备答案找到但不知道如何
- 在Windows 7上不起作用,但它适用于Windows 8 dll。
- 可变参数模板转换为 std::function<R(ARGS...)>适用于 GCC 而不是 MSVC2013,为什么?
- C++11 cmath 函数不在 std 命名空间中,适用于 android NDK w/gcc-4.8 或 clang