- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的游戏中,成为叛徒的士兵
将自动从炮塔
、坦克
和很多持有人。 (MCVE)
一个士兵
可以同时驻留在1个炮塔
和1个坦克
中。士兵
最多可以驻留在 1 个炮塔
和最多 1 个坦克
中。
这是 Soldier
、Turret
和 Tank
类(在实际情况下,它们在 3 个文件中):-
#include <iostream>
#include <string>
#include <vector>
struct Soldier{
private: int team=0;
public: void setTeam(int teamP){
team=teamP;
//should insert callback
}
};
struct Turret{
Soldier* gunner=nullptr;
//currently it is so easy to access Turret's gunner
};
struct Tank {
std::vector<Soldier*> passenger;
//currently it is so easy to access Tank's passenger by index
};
std::vector<Soldier*> global_soldier;
std::vector<Turret*> global_turret;
std::vector<Tank*> global_tank;
这是 main()
。
目前,每当程序员想要设置任何 Soldier
实例的团队时,他都必须手动执行 ejection :-
int main(){
Soldier soldier1; global_soldier.push_back(&soldier1);
Turret turret1; global_turret.push_back(&turret1);
turret1.gunner=&soldier1;
//v game loop
soldier1.setTeam(2);
//v manual ejection (should be callback?)
for(auto& ele: global_turret){
if(ele->gunner==&soldier1){
ele->gunner=nullptr;
}
}
for(auto& ele: global_tank){
for(auto& elePass: ele->passenger){
if(elePass==&soldier1){
elePass=nullptr;
}
}
}
//^ manual ejection
std::cout<<"should print 1="<<(turret1.gunner==nullptr)<<std::endl;
}
这导致在每次调用Soldier::setTeam(int)
(维护问题)和性能问题后出现大量样板代码。
如何解决?
我不想失去的当前优势:-
- 很容易通过索引访问炮塔的炮手和坦克的一名乘客。
在 Soldier
中,我创建了一个回调中心 (callback_changeTeams
)。
在 Turret
和 Tank
中,我为 Soldier
创建了一个回调定义(Turret::ChangeTeam
和 Tank::ChangeTeam
).
这是工作代码。士兵
:-
class Soldier;
struct Callback{
public: virtual void changeTeam_virtual(Soldier* soldier)=0;
};
std::vector<Callback*> callback_changeTeams;
struct Soldier{
private: int team=0;
public: void setTeam(int teamP){
if(team==teamP){
}else{
team=teamP;
for(auto callback :callback_changeTeams)
callback->changeTeam_virtual(this);
}
//should insert callback
}
};
炮塔
:-
struct Turret;
std::vector<Turret*> global_turret;
struct Turret{
Soldier* gunner=nullptr;
struct ChangeTeam : public Callback{
public: virtual void changeTeam_virtual(Soldier* soldier){
for(auto& ele: global_turret){
if(ele->gunner==soldier){
ele->gunner=nullptr;
}
}
}
};
};
坦克
(类似于炮塔的):-
struct Tank;
std::vector<Tank*> global_tank;
struct Tank {
std::vector<Soldier*> passenger;
struct ChangeTeam : public Callback{
public: virtual void changeTeam_virtual(Soldier* soldier){
for(auto& ele: global_tank){
for(auto& elePass: ele->passenger){
if(elePass==soldier){
elePass=nullptr;
}
}
}
}
};
};
主要:-
std::vector<Soldier*> global_soldier;
int main(){
Turret::ChangeTeam turretCallback;
Tank::ChangeTeam tankCallback;
callback_changeTeams.push_back(&turretCallback);
callback_changeTeams.push_back(&tankCallback);
Soldier soldier1; global_soldier.push_back(&soldier1);
Turret turret1; global_turret.push_back(&turret1);
turret1.gunner=&soldier1;
//v game loop
soldier1.setTeam(2);
//v should be callback
std::cout<<"should print 1="<<(turret1.gunner==nullptr)<<std::endl;
}
缺点:-
<强>1。 Turret
和 Tank
之间的重复代码。
还不错,但在实际情况中,我有很多类似 Turret
的东西(存储指向 Soldier
的指针)和类似 Tank
的东西(存储 Soldier
的数组)。这将是很多代码重复。
<强>2。仍然表现不佳。每当我只是更改 Soldier
的团队设置时,我都必须迭代每个 Turret
和 Tank
。
这可以通过缓存父级 Turret
和 Tank
来解决,因此不需要迭代。
但是,在实际情况中,我有很多父类型,它们会很脏,例如:-
struct Soldier{
//... some field / functions ...
Turret* parentTurret;
Tank* parentTank;
SomeParentClass1* parent1;
SomeParentClass2* parent2; // bra bra bra.. ... dirty messy
};
我的随机想法(用处不大):智能指针(std::shared_ptr
); std::unordered_map
;改变设计模式;使回调作为批处理提交;我正在使用实体组件系统。
最佳答案
正如您自己所说,有一个通用术语“支架”涵盖了坦克和炮塔。
在您的类(class)中建模。然后你可以在 soldier 中维护对它所在的任何内容的引用,并让它适本地处理士兵的退出/进入。这样一来,您只需搜索坦克中非常短的士兵名单,并且只搜索士兵实际坐在的那个坦克。
struct Soldier;
struct Holder
{
public:
virtual void AddSoldier(Soldier* Entering)=0;
virtual void ExitSoldier(Soldier* Exiting)=0;
}
struct Turret:
public holder
{
public:
virtual void AddSoldier(Soldier* Entering)
{
gunner=Entering;
AttachedTo->AddSoldier(Entering);
}
virtual void ExitSoldier(Soldier* Exiting)
/* this only covers the complete way of exiting,
add another method for moving only into the tank */
{ if(gunner=Exiting)
{
gunner=nullptr;
}
if(AttachedTo)
{
AttachedTo->ExitSoldier(Exiting);
}
}
Soldier* gunner=nullptr;
Tank* AttachedTo;
};
struct Tank
: public holder
{
virtual void AddSoldier(Soldier* Entering)
{
/* push Entering,
if not in already */
}
virtual void MoveSoldierToTurretIfFree(Soldier* NewGunner)
{/* you know .. */}
virtual void ExitSoldier(Soldier* Exiting)
{
AttachedTurret->ExitSoldier(Exiting);
/* find and remove Exiting,
tolerating if already left */
}
std::vector<Soldier*> passenger;
struct turret* AttachedTurret;
};
struct Soldier{
private: int team=0;
Holder* Within;
public: void setTeam(int teamP){
team=teamP;
//should insert callback
}
void IsTraitor (void)
{
Within->ExitSolder(this);
Within=nullptr;
}
};
我对 public
有点慷慨,当然可以在那里进行一些微调。
我将方法代码直接写入类中,您必须将其移动到代码文件或至少单独的实现中才能使其可编译;否则前向声明的 Soldier 类可能不够用。
关于c++ - 清除指针的回调(MCVE : auto eject traitor Soldier from Vehicle),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58177517/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我在64位linux下使用c++,编译器(g++)也是64位的。当我打印某个变量的地址时,例如一个整数,它应该打印一个 64 位整数,但实际上它打印了一个 48 位整数。 int i; cout <<
我是一名优秀的程序员,十分优秀!