繁体   English   中英

我想要返回类型指针,但我希望我的函数返回派生类的指针

[英]I want return type pointer but i want my function to return pointer of derive class

Dragon* Dragon::spawn() {
    int x = rand() % 5;
    int y;
    if (!if_locked(x)) //is a function to see if that id is unlocked because i want some dragon to be generated only if you have certain xp so it will call func again until unlocked id is generated
        spawn();
    else
        y = unlocking(m); // Y is generated form 1-5, I have assigned Id to each derive class whosoever id matches Y that pointer will be returned

    if (y == 1) {
        GroundDragon* pt;
        return pt;
        }

    if (y == 2) {
        WaterDragon* st;
        return st;
    }
    if (y == 3) {
        IceDragon*bt;
        return bt;
    }
    if (y == 4) {
        FireDragon* ct;
        return ct;
    }
    if (y == 5) {
        DarkDragon* dark;
        return dark;
    }
}

正如你所看到的,我犯了语法错误,希望有人能指导我

函数的返回类型是基类,if语句中的所有类都是派生类

所以我以后可以使用这个功能

 template<class T>
 void spawner(T*) {// I will spawn() fucntion as perimeter at time of call 
   T = new T;
 }

请原谅我,如果我上次发布问题时我重复了这个问题并没有引起我期待的关注,所以我修改了我的代码,希望现在很清楚了`

int Dragon::unlocking(Mage m) {


if (m.getxp() <= 50 and m.getxp() <= 100) {
    unlock[0] = 1;
    cout << "Congratulation GroundDragon unlocked " << endl;
    return 1;
}

if (m.getxp() > 100 and m.getxp() < 150) {
    unlock[1] = 1;
    cout << "Congratulation WaterDragon unlocked " << endl;
    return 2;
}
if (m.getxp() > 150 and m.getxp() < 175) {
    unlock[2] = 1;
    cout << "Congratulation IceDragon unlocked " << endl;
    return 3;
}

if (m.getxp() > 175 and m.getxp() < 500) {
    unlock[3] = 1;
    cout << "Congratulation FireDragon unlocked " << endl;
    return 4;
}

if (m.getxp() > 500) {
    unlock[4] = 1;
    cout << "Congratulation DarkDragon unlocked " << endl;
    return 5;
}

}

bool Dragon::if_locked(int x) {
if (unlock[x] == 1) {
    return true;
}
else
    return false;

}

在此处输入图片说明 *我对智能指针不满意(我以前从未使用过它们,但如果您告诉我如何将其称为 main,我很乐意使用它们 * 我使用了原始指针,但它仍然显示错误,请帮助 mw

这个想法是合理的,只是执​​行失败了。

如果你想要一个工厂函数来返回不同的对象,然后这些对象会以多态的方式运行,这完全没问题,但有一件重要的事情——你需要返回实际的对象。

您的工厂函数的返回类型为Dragon* 这意味着无论您返回什么值,它将是一个指向(某种类型的) Dragon的指针。 但是,该指针的值可以指向实际上是FireDragonIceDragon等实例的对象。当您创建此类对象的实例时,指向此类实例的指针可以转换为适当的返回类型并返回。

但是,在您的情况下,当您创建指向某种龙的指针类型的临时对象时,您实际上并没有用实例填充它们。 它们都是用一个未指定的值创建的,然后该值被转换为一个类型为Dragon*的未指定值,无法提取它是从哪种类型转换而来的信息。

所以,为了让它以通常的方式工作,我们只需要创建一个适当类型的新实例并返回它。 我们不想在转移所有权时从函数返回原始指针,所以std::unique_ptr是一个更好的选择:

std::unique_ptr<Dragon> Dragon::spawn() {
    int x = rand() % 5;

    /* note - this bit of code doesn't make any sense whatsoever
    int y;
    if (!if_locked(x)) //is a different function
        spawn();
    else
        y = unlocking(m); //is also a different function
    */

    // note that `rand() % 5` will produce values 0 through 4.
    switch(x) {
        case 0: return std::make_unique<GroundDragon>();
        case 1: return std::make_unique<WaterDragon>();
        case 2: return std::make_unique<IceDragon>();
        case 3: return std::make_unique<FireDragon>();
        case 4: return std::make_unique<DarkDragon>();
    }
}

现在您根本不需要spawner功能; 您可以直接使用返回值。

我认为第一个重要的教训是关于初始化指针。

线
GroundDragon* pt;
声明有一个指向GroundDragon对象的指针,到目前为止GroundDragon顺利。 然而,这并不能创建一个对象。
打个比方:你创建了一个能够指向村庄方向的方向标志,但你没有建造一个实际的村庄来指向它。 而现在,它只是指向某个随机方向。
由于未初始化, pt包含一个随机值,而不是GroundDragon类型的现有对象的地址。 用它做任何事情很可能会导致不好的事情(特别是未定义的行为)。
为了初始化它,你可以这样写
GroundDragon* pt = new GroundDragon;
这会在堆上创建一个GroundDragon类型的对象,并将其地址分配给pt
还要注意,每个new需要delete以保持内存干净,只是先发制人地提及这一点。

这是非常重要的知识 - 请务必了解这一点。

我想写这篇文章是为了向您展示如何使用原始指针,作为 Bartek Banachewicz 答案的补充,他没有展示初始化原始指针的方法。 但是,他使用智能指针所做的事情显然是比使用原始指针更好的方法。 但是,我想说您还能够使用原始指针非常重要。 从长远来看,确保能够做到这两点,并尽可能使用智能指针。

编辑:现在对于代码的另一部分,

int x = rand() % 5;
int y;
if (!if_locked(x)) //is a function to see if that id is unlocked because i want some dragon to be generated only if you have certain xp so it will call func again until unlocked id is generated
    spawn();
else
    y = unlocking(m);

首先,请注意调用spawn(); 忽略返回值。 这意味着,它根本没有影响。 你可能想写的是return spawn(); .
其次, if(!if_locked(x))在我看来与它应该是相反的。 “如果没有锁定”意味着“如果解锁”,在这种情况下,它不应该再试一次,而是继续,对吧?
而且,是你用来unlocking Dragon成员的Mage m吗? 听起来更像是一个指针,如果你不是特别想要像Dragon拥有Mage这样的关系。

无论如何,我会继续unlocking spawn spawn这样的方法说它有利于产卵。 尤其是打印某些东西被解锁并不是我直觉上理解的生成过程的一部分。 另外,我会以不同的方式命名,因为“解锁”是一种状态而不是命令。 check_for_new_unlocks或类似的东西一样,这听起来像一个命令。 并将其与spawn分开进行。

另外,请注意,您检查了狭窄的经验间隔 - 您确定不会发生间隔从未被触发的情况,因为角色可能会在间隔内前进而从不调用其间的方法吗?

此外,我会调用表示某些内容是否以不同方式解锁的数组。 “解锁”听起来像一个命令。 “可用”怎么说?

此外,我发现spawn的递归调用在尝试x其他值时可读性较差,但这是意见。 我想去

int x = rand() % 5;
while(not available[x])
{
    x = rand() % 5;
}

不过,根据实际机制,也许这可以做得更聪明。 您可以创建随机变量,如int x = rand() % total_available(); 例如。

请注意,其中很多都是基于意见的。 在这方面,我想向您指出CodeReview - 一旦您的代码正常工作,您可能希望将其发布在那里,以便人们帮助您在几个不同方面改进它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM