一种克服对象切片的方法
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();
由于对象切片,它打印
"Person..."
我试过使用 unique_ptr
并得到了相同的结果。
我尝试声明 copy function
例如
vitual clone() const{ return new Person(*this);}
在基类中
并且在导出的 classes 中我声明了
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;
}
我仍然被对象切片击倒了。我尝试了各种 things/approaches/methods 并且都导致了对象切片。
有没有办法在函数的参数中不使用 new
关键字,例如 [=22] =]
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() 以通过 *
获取 Person 参数
void add( string name , Person* a ){
m[ name ] = a;
}
将对象传递给 add()
函数的方式更改为在自由存储上分配的对象。
在Person
class
中定义自己的复制构造函数
更改您的 add()
函数以通过引用接受其参数:
void add( string name , const Person &a){
Person *one = a.clone();
m[ name ] = one;
}
当您按值传递对象时,您正在对对象进行切片。复制并切片它。您需要将参数作为参考传递。
你所有的 clone()
方法都已经是常量了。好
如果你不想让你的对象被切片,你只需通过引用或指针传递:
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;
}
有没有办法在不使用 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();
由于对象切片,它打印
"Person..."
我试过使用 unique_ptr
并得到了相同的结果。
我尝试声明 copy function
例如
vitual clone() const{ return new Person(*this);}
在基类中
并且在导出的 classes 中我声明了
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;
}
我仍然被对象切片击倒了。我尝试了各种 things/approaches/methods 并且都导致了对象切片。
有没有办法在函数的参数中不使用 new
关键字,例如 [=22] =]
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() 以通过 *
获取 Person 参数void add( string name , Person* a ){
m[ name ] = a;
}
将对象传递给 add()
函数的方式更改为在自由存储上分配的对象。
在Person
class
更改您的 add()
函数以通过引用接受其参数:
void add( string name , const Person &a){
Person *one = a.clone();
m[ name ] = one;
}
当您按值传递对象时,您正在对对象进行切片。复制并切片它。您需要将参数作为参考传递。
你所有的 clone()
方法都已经是常量了。好
如果你不想让你的对象被切片,你只需通过引用或指针传递:
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;
}