C++ 抽象类指针参数的默认值
我正在尝试这样做:C++ 抽象类指针参数的默认值,c++,class,polymorphism,abstract-class,default-value,C++,Class,Polymorphism,Abstract Class,Default Value,我正在尝试这样做: class Movement { public: virtual void move() = 0; }; class Walk : public Movement { public: void move() { cout << "walking"; } }; class Run : public Movement { public: void move() { cout << "run"
class Movement {
public:
virtual void move() = 0;
};
class Walk : public Movement {
public:
void move() { cout << "walking"; }
};
class Run : public Movement {
public:
void move() { cout << "run"; }
};
class Model {
unique_ptr<Animal> animal;
unique_ptr<Movement> movement;
public:
Model(unique_ptr<Animal> animal = make_unique<Human>(), unique_ptr<Movement> movement = make_unique<Walk>()){
this->animal = std::move(animal);
this->movement = std::move(movement);
}
void print() {
cout << "This Model consist of one: ";
animal->print();
cout << ", which is: ";
movement->move();
}
};
int main() {
Model first/*no () here!*/, second(make_unique<Lion>(), make_unique<Run>());
first.print();
cout << endl;
second.print();
return 0;
}
类移动{
公众:
虚空移动()=0;
};
班级步行:公众运动{
公众:
void move(){cout这实际上是一个设计问题。在Model
类设计中,您需要决定对象所有权,或者将决定推迟到调用代码。在后一种情况下,您不能使用默认参数(除非您想要全局常量人类
和行走
,但我不推荐)
拥有默认参数的一种方法是确定模型
拥有动物
和运动
的独占所有权,并为它们存储唯一的\u ptr
。如下所示:
class Movement {
public:
virtual void move() = 0;
};
class Walk : public Movement {
public:
void move() { cout << "walking"; }
};
class Run : public Movement {
public:
void move() { cout << "run"; }
};
class Model {
unique_ptr<Animal> animal;
unique_ptr<Movement> movement;
public:
Model(unique_ptr<Animal> animal = make_unique<Human>(), unique_ptr<Movement> movement = make_unique<Walk>()){
this->animal = std::move(animal);
this->movement = std::move(movement);
}
void print() {
cout << "This Model consist of one: ";
animal->print();
cout << ", which is: ";
movement->move();
}
};
int main() {
Model first/*no () here!*/, second(make_unique<Lion>(), make_unique<Run>());
first.print();
cout << endl;
second.print();
return 0;
}
类模型{
独特的ptr动物;
独特的ptr运动;
公众:
模型(独一无二的动物=独一无二的(),独一无二的运动=独一无二的()){
这个->动物=性病::移动(动物);
此->移动=标准::移动(移动);
}
作废打印(){
不能打印();
不能移动();
}
};
int main(){
第一个模型/*这里没有()!*/,第二个(make_unique(),make_unique());
第一,print();
cout您的问题是编译错误吗?有多种方法可以解决编译错误,但是考虑到您的问题是关于从抽象类继承的,我将重点讨论这个问题
首先,如您所提供的,您的<代码>动物< /Cord>类是一个抽象类,它不是所有的方法都是实例化的,因为C++的纯虚函数是由<代码>虚拟< /COD>关键字前缀指定的,<强>和<强> >定义为<代码>=0 < /代码>。
...
virtual void print() = 0;
...
通过将Animal
类设置为抽象类,可以编译以下代码:
#include <iostream>
using namespace std;
class Movement {
public:
virtual void move() = 0;
};
class Walk : public Movement {
public:
void move() { cout << "walking"; }
};
class Run : public Movement {
public:
void move() { cout << "run"; }
};
class Animal {
public:
virtual void print() = 0;
};
class Human : public Animal {
public:
void print() { cout << "Human"; }
};
class Lion : public Animal {
public:
void print() { cout << "Lion"; }
};
class Model {
Animal* animal;
Movement* movement;
public:
Model(Animal* animal = new Human(), Movement* movement = new Walk()) {
this->animal = animal;
this->movement = movement;
}
void print() {
cout << "This Model consist of one: ";
animal->print();
cout << ", which is: ";
movement->move();
}
};
int main() {
Model first = Model(),
second = Model(new Lion(), new Run());
first.print();
cout << endl;
second.print();
return 0;
}
否则,从概念上讲,在C++中您所做的一切都是可以完成的:为某个函数的参数列表中的基类指针指定一个默认值
重要:正如评论者正确指出的那样,您编码的模式是危险的:您的界面是这样的:用户可以选择性地提供动物
实例。问题是:如果模型
创建者这样做,那么可以合理地认为他正确地拥有该对象。如果如果没有,那么您的构造函数将创建一个新的Animal
实例,但是Model
既没有获得对象的所有权,也没有提供一个用户可以获得新Animal
实例所有权的界面。因此,这会造成内存泄漏。同样,代码风险是t的所有权不明确他在模型
构造器中使用了动物
实例。我想我找到了适合我情况的最佳解决方案
#include <iostream>
#include <memory>
using namespace std;
#包括
#包括
使用名称空间std;
类移动{
公众:
虚空移动()=0;
虚拟唯一_ptr movement()常量=0;
};
班级步行:公众运动{
公众:
空对象():对象不是指针,指针不是C++中的任何东西。你可以使用<代码>新< /C> >,但是这会明显地泄漏内存。这看起来像java代码,但是C++不是java.当你在代码< >代码()中声明“代码>模型第一个())/>代码时,使用重载而不是默认的论证。
,您首先声明了函数返回模型
。谷歌“最烦人的解析”再者:你知道指针和对象之间的区别吗?你不能创建一个对象并把它分配给一个指针,无论是默认参数值还是其他任何地方。C++不这样工作。不幸的是,代码比语言更响亮,没有人能够找出甚至没有显示的代码的问题。ῥεῖ 谢谢。我已经从您编译的源代码.Np中更新了答案,很高兴能提供帮助。Oops,在我们发布之前:py您至少应该在模型
析构函数中提到内存泄漏,而不进行适当删除(但是您仍然存在不确定所有权的问题)。问题是关于从抽象类继承。OP没有提供Animal::print
的定义。您的新Animal
和movement
方法传统上命名为clone
。有了这个名称,您的源代码将更容易理解。
#include <iostream>
using namespace std;
class Movement {
public:
virtual void move() = 0;
};
class Walk : public Movement {
public:
void move() { cout << "walking"; }
};
class Run : public Movement {
public:
void move() { cout << "run"; }
};
class Animal {
public:
virtual void print() {};
};
class Human : public Animal {
public:
void print() { cout << "Human"; }
};
class Lion : public Animal {
public:
void print() { cout << "Lion"; }
};
class Model {
Animal* animal;
Movement* movement;
public:
Model(Animal* animal = new Human(), Movement* movement = new Walk()) {
this->animal = animal;
this->movement = movement;
}
void print() {
cout << "This Model consist of one: ";
animal->print();
cout << ", which is: ";
movement->move();
}
};
int main() {
Model first = Model(),
second = Model(new Lion(), new Run());
first.print();
cout << endl;
second.print();
return 0;
}
#include <iostream>
#include <memory>
using namespace std;
class Movement {
public:
virtual void move() = 0;
virtual unique_ptr<Movement> movement() const = 0;
};
class Walk : public Movement {
public:
void move() { cout << "walking"; }
unique_ptr<Movement> movement() const { return make_unique<Walk>(); }
};
class Run : public Movement {
public:
void move() { cout << "run"; }
unique_ptr<Movement> movement() const { return make_unique<Run>(); }
};
class Animal {
public:
virtual void print() = 0;
virtual unique_ptr<Animal> animal() const = 0;
};
class Human : public Animal {
public:
void print() { cout << "Human"; }
unique_ptr<Animal> animal() const { return make_unique<Human>(); }
};
class Lion : public Animal {
public:
void print() { cout << "Lion"; }
unique_ptr<Animal> animal() const { return make_unique<Lion>(); }
};
class Model {
unique_ptr<Animal> animal;
unique_ptr<Movement> movement;
public:
Model(const Animal& animal = Human(), const Movement& movement = Walk()) {
this->animal = animal.animal();
this->movement = movement.movement();
}
void print() {
cout << "This Model consist of one: ";
animal->print();
cout << ", which is: ";
movement->move();
}
};
int main() {
Model first = Model(), second = Model(Lion(), Run());
first.print();
cout << endl;
second.print();
return 0;
}