抽象类指针参数的默认值

如何解决抽象类指针参数的默认值

我正在尝试做这样的事情:

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类设计中,您需要确定对象所有权,或将决定推迟到调用代码。在后一种情况下,您不能使用默认参数(除非您希望具有全局常量HumanWalk,但我不建议这样做)。

使用默认参数的一种方法是,确定Model具有AnimalMovement的排他所有权,并将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 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res