一种克服对象切片的方法
A way how to overcome object slicing
有没有一种方法可以在不使用new关键字作为函数参数的情况下解决对象切片问题?我有基本对象
class Person{
public:
Person(string name , int age ){
this -> name = name;
this -> age = age;
}
virtual void getInfo(){
cout << "Person " << name << " " << age;
}
void add( string name , Person a){
Person *one = new Person(a);
m[ name ] = one;
}
void print(){
for( auto &x: m )
x.second -> getInfo()
}
protected:
string name;
int age;
map< string , Person*> m;
};
派生对象
class Kid : public Person{
public:
Kid(string name, int age):Person(name,age){};
virtual void getInfo( ){
cout << "Kid " << name << " " << age;
}
};
class Adult : public Person{
public:
Adult(string name, int age):Person(name,age){};
virtual void getInfo( ){
cout << "Adult " << name << " " << age;
}
};
尝试调用
Person one("John", 25);
one.add("first",Kid("Mathew",15));
one.add("second",Adult("Leo",55));
one.print();
由于对象切片,它打印
"人…"
我尝试过使用unique_ptr
,但最终得到了相同的结果。我尝试声明copy function
,例如
vitual clone() const{ return new Person(*this);}
碱性
在派生类中,我声明了
Kid* clone() const{ return new Kid(*this);}
Adult* clone() const{ return new Adult(*this);}
并编辑了添加功能。
void add( string name , Person a){
Person *one = a.clone();
m[ name ] = one;
}
我仍然被一个物体切片机卡住了。我尝试过各种各样的东西/方法/方法,所有这些都导致了对象切片。
有没有一种方法可以在函数的参数中不使用new
关键字来创建这样的东西(包含基类的derivec类的映射),例如
Person one("bla",5);
one.add("asd", new Kid("one",15))
谢谢你的帮助。
//代码的当前状态
class Person{
public:
Person(string name , int age ){
this -> name = name;
this -> age = age;
}
virtual void getInfo(){
cout << "Person " << name << " " << age;
}
void add( string name , const Person &a){
Person *one = a.clone();
m[ name ] = one;
}
void print(){
for( auto &x: m ){
x.second -> getInfo();
cout << endl;
}
}
virtual Person* clone() const{ return new Person(*this);}
protected:
string name;
int age;
map< string , Person*> m;
};
class Kid : public Person{
public:
Kid(string name, int age):Person(name,age){};
virtual void getInfo( ){
cout << "Kid " << name << " " << age;
}
Kid* clone() const{ return new Kid(*this);}
};
class Adult : public Person{
public:
Adult(string name, int age):Person(name,age){};
virtual void getInfo( ){
cout << "Adult " << name << " " << age;
}
Adult* clone() const{ return new Adult(*this);}
};
int main(){
Person one("John", 25);
one.add("first",Kid("Mathew",15));
one.add("second",Adult("Leo",55));
one.print();
}
更改add()
函数以通过引用接受其参数:
void add( string name , const Person &a){
Person *one = a.clone();
m[ name ] = one;
}
当您按值传递对象时,您正在对其进行切片。它复制并切片。您需要将参数作为引用传递。
您的所有clone()
方法都已是常量。好的
通过*更改add()以获取Person参数
void add( string name , Person* a ){
m[ name ] = a;
}
更改将对象传递给add()
函数的方式,以将对象传递到空闲存储中分配的对象。
在Person
类中定义自己的复制构造函数
如果你不想让你的对象被切片,你只需要通过引用或指针:
struct Foo {
virtual void print() const {std::cout << "FOO" <<std::endl;}
};
struct Bar : Foo {
void print() const {std::cout << "BAR" <<std::endl;}
};
void slicingFunc(Foo foo){ foo.print(); }
void nonSlicingFunc(const Foo& foo) { foo.print(); }
int main() {
Bar b;
slicingFunc(b); // prints FOO
nonSlicingFunc(b); // prints BAR
return 0;
}
相关文章:
- 避免矢量中的对象切片<Base><shared_ptr>
- 专门化模板覆盖函数/避免对象切片
- C++ 被此代码与多态性、指针和对象切片混淆
- 我们能胜过对象切片吗?
- 如何在考虑对象切片的同时通过传入单个 Base 对象来打印出数组中的对象?
- 成员变量和对象切片
- 如何在不引入未来对象切片的情况下实现 ICloneable
- 避免对象切片
- 故意对对象切片是一种可行的技术吗?
- 对象切片:通过按值派生为 Base - 安全还是危险?
- C++ CRTP 派生类对象切片
- C++ - 即使在使用指针后也能进行对象切片
- 了解对象切片
- 使用对象切片可靠地从多个基类之一中复制
- 对象切片和隐式类型转换
- 一种克服对象切片的方法
- 按引用传递可避免对象切片
- 使用CRTP时的对象切片
- 对象切片:从基类对象访问分层的类方法
- 这会导致对象切片吗?