如何解决抽象类指针参数的默认值
我正在尝试做这样的事情:
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;
}
我们如何设置抽象类指针的默认值以及如何将它们作为像main这样的参数传递给它?
我也希望能够像这样只通过单行从main传递参数,而无需事先进行初始化。
任何人都可以帮助我解决C ++中的问题吗?
我尝试了很多,但没有运气。
我正在寻找一种解决方法,可以将抽象类用作其他类的参数。
我知道不能将对象分配给指针,我只是不知道该怎么做才能满足我的要求,即抽象类作为具有默认值的参数。
这是我最近一次尝试使用精确代码,但是不幸的是,使用new
,有人知道如何摆脱new
并达到预期的结果吗?
注意:
我的实际代码非常复杂,基本上是使用抽象类实现多态并将这些抽象类作为参数传递给具有默认参数的另一个类,如果有 ANY 其他方式来执行类似操作,我将非常感谢帮助。
解决方法
这确实是一个设计问题。在Model
类设计中,您需要确定对象所有权,或将决定推迟到调用代码。在后一种情况下,您不能使用默认参数(除非您希望具有全局常量Human
和Walk
,但我不建议这样做)。
使用默认参数的一种方法是,确定Model
具有Animal
和Movement
的排他所有权,并将unique_ptr
存储到其中。像这样:
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;
}
,
我认为我针对自己的情况提出了最佳解决方案。
#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;
}
,
您的问题是编译错误吗?解决编译错误的方法有多种,但是鉴于您的问题是关于从抽象类继承的问题,我将着重于此。
首先,按照规定,您的analysis_options.yaml
类是 不是 抽象类。由于抽象类的所有方法都是纯虚拟的,因此无法实例化。在C ++中,纯虚函数由Animal
关键字前缀,在其定义中后缀virtual
的 和 指定。例如
= 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;
}
提供实现来使您的代码可编译。以下代码也是可编译的,但是Animal::print()
不是 抽象类,因为它提供了Animal
的实现,而不是在{{ 1}}:
Animal::print()
否则,从概念上讲,您正在做的事情很好,并且完全可以在C ++中进行:将默认值分配给某个函数的参数列表中的基类指针。
重要:正如评论者正确指出的那样,您编码的模式很危险:您的界面使用户可以 可选 提供一个= 0
实例。问题是:如果#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(),new Run());
first.print();
cout << endl;
second.print();
return 0;
}
创建者这样做了,那么可以合理地说他是该对象的正确所有者。如果他不这样做,那么您的构造函数 将创建一个新的Animal
实例,但是Model
既不拥有该对象的所有权,也不提供用户使用的接口可以拥有新的Animal
实例的所有权。因此,这会导致内存泄漏。同样,代码危险在于Model
构造函数中使用的Animal
实例的所有权模棱两可。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。