Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 抽象类指针参数的默认值_C++_Class_Polymorphism_Abstract Class_Default Value - Fatal编程技术网

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;
}