C++ 一种克服对象切片的方法
有没有一种方法可以避免在不使用新关键字作为参数的情况下进行对象切片?我有一个基本对象C++ 一种克服对象切片的方法,c++,oop,inheritance,polymorphism,object-slicing,C++,Oop,Inheritance,Polymorphism,Object Slicing,有没有一种方法可以避免在不使用新关键字作为参数的情况下进行对象切片?我有一个基本对象 class Person{ public: Person(string name , int age ){ this -> name = name; this -> age = age; } virtual void getInfo(){ cout << "P
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;
};
由于对象切片,它会打印
“人……”
我尝试过使用unique\u ptr
,结果都是一样的。
我尝试声明复制函数
,例如
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();
}
班级人员{
公众:
Person(字符串名称,整数年龄){
此->名称=名称;
这个->年龄=年龄;
}
虚拟void getInfo(){
cout更改add()以通过*
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;
}
struct Foo{
virtual void print()const{std::cout“使用new关键字作为函数的参数”是什么意思??如果你想避免对象切片,只需传递一个指针或引用……你能举个例子吗?我已经试着让它工作了几个小时了,但我试着同时传递引用和指针却没有成功,这是什么意思,clone()函数不够吗?你能举个例子吗?像void add这样的API(std::unique_ptr)
似乎在暗示它自己。它仍然会被切片,只打印“Person…”你没有真正展示你是如何声明你的clone()方法的。你只是对它进行了解释。因此,任何答案最多只能是猜测。在任何情况下,这就是调试器的用途。逐行检查你的代码,看看哪个对象是clone()方法被调用。我确实编写了如何声明clone()函数,在我的问题中有一个完整的声明。仅作为附加注释,在您展示了没有它的代码后进行了解释。我已经更新了整个代码的问题,它看起来如何
void add( string name , const Person &a){
Person *one = a.clone();
m[ name ] = one;
}
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;
}