“explicit”对静态上播的影响
Effect of `explicit` on static upcasting
当基类中唯一的候选构造函数被标记为explicit
时,派生类的实例是否可以隐式转换为基类的实例?
我运行了这个:
struct Base {
Base() {}
explicit Base(Base const& b) {}
};
struct Derived : Base {};
int main() {
Derived d;
Base b = d;
}
得到这个:
错误:没有匹配的函数调用'Base::Base(Derived&)'
然后我运行这个:
struct Base {
Base() {}
Base(Base const& b) {}
};
struct Derived : Base {};
int main() {
Derived d;
Base b = d;
}
没有错误。
但我不完全相信这个测试的成功是由于explicit
而不是由于合成。特别是,我不认为explicit
关心参数的类型,但它会迫使我写Base b = static_cast<Base>(d)
…这两种情况我都不做
不是转换失败。复制初始化需要一个可访问的复制构造函数。
struct Base {
Base() {}
explicit Base(Base const& b) {}
};
int main() {
Base d;
Base b = d;
}
事后看来,似乎很清楚。
在这里起作用的元素有:
- 唯一要合成的候选构造函数是
Base(Base const&)
,我不提供构造函数Base(Derived const&)
。 - 所述构造函数是
explicit
,但我没有提供显式转换。
所以,答案是"不"
This:
int main() {
Derived d;
Base b = d;
}
不是向上转换。这就是创建一个名为b
的新对象,它包含d
值的副本。为了进行上转换,必须使用多态值(引用或指针)。因此,向上转换将是:
int main() {
Derived d;
Base &b = d;
}
变量b
包含对d
的Base
部分的引用。如果Base
有某个公共成员int baseValue;
,则b.baseValue
引用的数据与d.baseValue
完全相同。例如:
int main() {
Derived d;
Base &b = d;
d.baseValue = 10;
cout << b.baseValue << endl;
}
这将写10
。如果b
不是一个引用,而是一个普通对象,那么在d
的值被改变之前,它会从d
复制(初始化)的值。因此,改变其中一个不会改变另一个。
explicit
关键字的目的是防止像Base b = d
这样的语法起作用。如果你创建了一个构造函数explicit
,你是在说,"我不希望编译器隐式地调用这个复制构造函数。如果用户要使用它,那么他们必须明确地这样说。如果你想隐式转换类型,那么你必须这样说。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- #为""定义宏;静态";针对不同的上下文
- cmake如何在fedora工作站中找到boost静态库包
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- cmake在我的项目中所需的所有静态库都不成功
- C++从另一个类访问公共静态向量的正确方法是什么
- 基于boost的程序的静态链接——zlib问题
- 在静态库中嵌入类方法
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 如何在C++中获得"静态纯虚拟"功能?
- 使用"静态"如何影响我的代码速度?
- 当只有静态方法受到影响时,如何解决C++中的链接器错误?
- Eclipse CDT链接选项-静态libgcc-静态libstdc++不影响Windows上的行为
- 更改静态库的"动态 RTL"设置有什么影响?
- “explicit”对静态上播的影响
- 对OpenMP中静态调度开销的影响
- -static-libstdc++ GCC标志会影响Linux上生成静态库(*.a)吗?
- 静态数组常量是否会影响共享库布局