防止切片的惯用方法? 有时候,C++默认允许切片是一个烦人的问题。比如说 struct foo { int a; }; struct bar : foo { int b; }; int main() { bar x{1,2}; foo y = x; // <- I dont want this to compile! } structfoo{inta;}; 结构条:foo{intb;}; int main(){ 条x{1,2}; foo y=x;//
通过声明复制构造函数受保护,可以防止基类被复制到派生类的成员函数之外以及基类本身:防止切片的惯用方法? 有时候,C++默认允许切片是一个烦人的问题。比如说 struct foo { int a; }; struct bar : foo { int b; }; int main() { bar x{1,2}; foo y = x; // <- I dont want this to compile! } structfoo{inta;}; 结构条:foo{intb;}; int main(){ 条x{1,2}; foo y=x;//,c++,inheritance,object-slicing,C++,Inheritance,Object Slicing,通过声明复制构造函数受保护,可以防止基类被复制到派生类的成员函数之外以及基类本身: struct foo { // ... protected: foo(foo&) = default; }; 我不确定是否有命名的习惯用法,但您可以向重载集中添加一个已删除的函数,该函数比基类切片操作更匹配 struct foo { int a; foo() = default; // you have to add this because of the temp
struct foo {
// ...
protected:
foo(foo&) = default;
};
我不确定是否有命名的习惯用法,但您可以向重载集中添加一个已删除的函数,该函数比基类切片操作更匹配
struct foo
{
int a;
foo() = default; // you have to add this because of the template constructor
template<typename T>
foo(const T&) = delete; // error trying to copy anything but a foo
template<typename T>
foo& operator=(const T&) = delete; // error assigning anything else but a foo
};
structfoo
{
INTA;
foo()=default;//由于模板构造函数的原因,您必须添加它
模板
foo(const T&)=delete;//尝试复制除foo以外的任何内容时出错
模板
foo&operator=(const T&)=delete;//分配除foo以外的任何内容时出错
};
然后,您只能复制构造或将
foo
复制分配给foo
。任何其他类型都会选择函数模板,您将在使用已删除函数时出错。这意味着您的类以及使用它的类不再是聚合。因为添加的成员是模板,所以它们不被视为复制构造函数或复制赋值运算符,因此您将获得默认的复制和移动构造函数和赋值运算符。自2011年以来,惯用的方法一直是使用自动
:
#include <iostream>
struct foo { int a; };
struct bar : foo { int b; };
int main() {
bar x{1,2};
auto y = x; // <- y is a bar
}
#包括
结构foo{int a;};
结构条:foo{intb;};
int main(){
条x{1,2};
自动y=x;//但是我不能再复制foo
s了:(如果可能的话,我想阻止只将一个条复制到一个foo,但这不会阻止像这样的显式切片:foo y=static\u cast(x)
。也就是说,可能操作不是问题。如果我理解正确,这是防止函数参数在general@user463035818.我一直在使用它,因为我问了这个问题。我把它看作是反向SFINAE。你做了你想编译的重载,然后添加一个删除的模板,每停止一次还有一件事。事实上,我有点急于接受这个答案。这项技术很棒,但事实上它为专门处理各种不需要的任务打开了大门,尽管如果我不得不在爪哇语的“不惜一切代价防止一切可能的愚蠢”和蟒蛇语的“我们都是成年人”之间做出选择,那么我知道该选什么;)最简单的方法是不使用继承。您必须将foo
作为bar
@KevinZ的成员变量
#include <iostream>
struct foo { int a; };
struct bar
{
bar(int a, int b)
: foo_(a)
, b(b)
{}
int b;
int get_a() const { return foo_.a; }
private:
foo foo_;
};
int main() {
bar x{1,2};
// foo y = x; // <- does not compile
}
#include <iostream>
struct foo {
int a;
protected:
foo(foo const&) = default;
foo(foo&&) = default;
foo& operator=(foo const&) = default;
foo& operator=(foo&&) = default;
};
struct bar : foo
{
bar(int a, int b)
: foo{a}, b{b}
{}
int b;
};
int main() {
auto x = bar (1,2);
// foo y = x; // <- does not compile
}