gpt4 book ai didi

c++ - 返回与定义的多态函数不同的类型

转载 作者:行者123 更新时间:2023-11-30 04:21:48 24 4
gpt4 key购买 nike

我遇到的问题是多态类:动物类有一个函数 "virtual animal* get() = 0;" 在狗类中定义为 “dog* get() { speak2(); return this; }”

我不久前在某处读到,以这种方式更改返回类型是合法的,但它似乎并没有像我预期的那样工作:调用 get 函数时它会打印预期值,但是当我尝试分配将值返回给 dog 类指针我得到一个无效的转换错误,当我尝试调用 speak2() 函数时它说它没有这样的成员。

我正在寻找的是能够调用类似“barn.front()->get()->speak2();” 的东西。有什么方法可以在没有任何 dynamic_casts 或任何此类转换的情况下实现与此类似的东西?

我以合乎逻辑的方式命名了这些类,以便于阅读,并且还在以下代码中以注释的形式添加了一些注释:

#include <iostream>
#include <vector>
using namespace std;

class animal
{
public:
virtual ~animal() {}
virtual void speak1() = 0;
virtual animal* get() = 0;
};

class dog : public animal
{
public:
void speak1() { cout << "print-speak1!"; }
void speak2() { cout << "print-speak2!"; }
dog* get() { speak2(); return this; }
};

int main()
{
vector<animal*> barn;

barn.push_back(new dog());

barn.front()->speak1(); // prints "print-speak1!"
barn.front()->get(); // prints "print-speak2!"

barn.front()->get()->speak2();
// error: 'class animal' has no member named 'speak2'
// but then why does "barn.front()->get();" print "print-speak2!"?

dog* dogptr = barn.front()->get();
// error: invalid conversion from 'animal*' to 'dog*' [-fpermissive]

dogptr->speak2();
// for the sake of -Werror=unused-variable

for(vector<animal*>::iterator i = barn.begin(); i != barn.end(); ++i)
{
delete *i;
}
barn.clear();

return 0;
}

最佳答案

您的代码在不同时间发生了两件事。首先,编译器将 barn.front() 的返回类型视为 animal*。无论你做什么。在 animal* 类型上调用成员 speak2() 总是失败。

您的成员 get() 是一个虚函数,并且 barn.front()->get(); 行是使用虚拟调度调用的。这意味着被调用的函数仅在运行时是已知的,基于什么是真实(所谓的动态)动物的类型。这样您就可以针对每只动物修改 get() 的行为。

get() 的不同返回值在这里无关紧要。编译器所做的类型检查(显然)是在编译时完成的,因此针对 animal::get()。协变返回类型仅在直接调用静态类型 dog 的对象时才有用。

在您的情况下,一种骇人听闻的方法是将类型转换为 dog,例如

static_cast<dog*>(barn.front())->speak2();

当然,如果 barn.front() 的实际类型不是狗,你就会被烧死。我指的是未定义的行为——程序可能会崩溃、抛出异常或静默地继续处理损坏的数据。

在我看来,更正确的方法是将不同的操作分离到一个通用接口(interface)中,例如:

class animal
{
public:
virtual ~animal() {}
virtual void makeSound() = 0;
};

class dog : public animal
{
public:
void bark() { cout << "hoof"; }
void makeSound() { bark(); }
};

class cat : public animal
{
public:
void meow() { cout << "meow"; }
void makeSound() { meow(); }
};

int main()
{
vector<animal*> barn;
barn.push_back(new dog());
barn.push_back(new cat());
barn.front()->makeSound();
barn[1]->makeSound();
}

关于c++ - 返回与定义的多态函数不同的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14198124/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com