为什么没有"交叉演员"工作?
以下创建此对象继承模型:
FOOD
/ \
CHEESE CAKE
在这里,我尝试static_cast
从cheese
到cake
的指针,制作芝士蛋糕:D。我从Apple Clang / LLVM收到以下错误:
ERROR: Static cast from 'Cheese *' to 'Cake *', which are not related by inheritance, is not allowed
但他们与继承有关:他们是兄弟姐妹。
为什么我无法将cheese
投射到cake
,就像我将int
投放到float
一样?为什么我不能"交叉演员"来自继承自相同基类的派生对象?
包含static_cast
和dynamic_cast
次尝试的最小,完整且可验证的示例,以突出显示错误。
#include <iostream>
#include <string>
class Food {
public:
Food(std::string brand):brand_(brand) {}
virtual ~Food() {};
std::string brand() { return brand_; }
virtual void cut()const { std::cout << "Food cut." << std::endl; }
void eat()const { std::cout << "Food eaten." << std::endl; }
private:
std::string brand_;
};
class Cheese : public Food {
public:
Cheese(std::string brand):Food(brand) {};
virtual void cut()const { std::cout << "Cheese cut.\n"; }
void eat()const { std::cout << "Cheese eaten.\n"; }
};
class Cake : public Food {
public:
Cake(std::string brand):Food(brand) {};
virtual void cut()const { std::cout << "Cake cut.\n"; }
void eat()const { std::cout << "Cake eaten.\n"; }
};
int main() {
Food f("tbd");
Cheese c("Cheddar");
Cake cc("Cheesecake");
Food * food_ptr;
Cheese *cheese_ptr, *cheeseCake_ptr;
Cake *cake_ptr;
food_ptr = &f;
food_ptr->cut(); //-> "Food cut."
food_ptr = &c;
food_ptr->cut(); //-> "Cheese cut." Result of virtual keyword.
cheese_ptr = dynamic_cast<Cheese*> (food_ptr);
cheese_ptr->cut(); //-> "Cheese Cut." The downcast worked
food_ptr = &cc;
cake_ptr = dynamic_cast<Cake*> (food_ptr);
cake_ptr->cut(); //-> "Cake Cut." pointer reassignment and downcast worked.
cheeseCake_ptr = dynamic_cast<Cheese*> (food_ptr);
cheeseCake_ptr->cut(); //-> "Cake cut." Again, Food* dynamically casted to Cheese*
/* ~~~ NOTE: THE FOLLOWING EXAMLES INTENTIONALLY THROW ERRORS ~~~ */
/*
Dynamic cross-cast attempt:
ERROR: Assigning to 'Cheese *' from incompatable type 'Cake *'
Dynamic cast: doensn't make sense, as the relationshiop between cheese and cake is not polymorphic
*/
cheeseCake_ptr = dynamic_cast<Cake*> (cheese_ptr);
cheeseCake_ptr->cut();
/*
Static cross-cast attempt:
ERROR: Static cast from 'Cheese *' to 'Cake *', which are not related by inheritance, is not allowed
Static cast: why doesn't this work? We know the data types.
*/
cheese_ptr = &c;
cake_ptr = &cc;
cheeseCake_ptr = static_cast<Cake*> (cheese_ptr);
std::cout << "\n\n";
return 0;
}
答案 0 :(得分:1)
not related by inheritance
意味着在同一个分支上......
你不应该将转换值误认为是转换指针(或反过来),它们是不同的类型转换。
int
到float
使用函数将给定类型的值转换为目标类型的值(请注意,此函数可以是显式或隐式,它隐含于该特定情况,即在语言中定义的)。在C ++中,您可以在自定义类类型上实现此功能,方法是为类A实现能够接收类型B值的ctor,或者通过为类B实现返回类型A值的强制转换操作符。
Cake *
到Cheese *
不会转换值,但会尝试以不同的方式查看给定对象。它是子类型多态(因此您需要使用dynamic_cast
)。给定您的类型层次结构,通过使用Food指针指向Cheese对象,可以轻松地将Cheese对象视为(不转换)为Food对象(就像您可以被不同的人看到的那样,(想想朋友,教授的方式)或者当你总是同一个人时,医生可以逮捕你!)。很明显(至少在你的等级中)奶酪不能被视为蛋糕,如果奶酪对象会如何对蛋糕的具体方法做出反应?你也是一只动物,也是一只狗,但我很难想象我会把你视为一只狗(你不会有4条腿不是吗? ...
如果你使用继承自Cheese和Cake的CheeseCake之类的多重继承,现在情况会略有改变。然后给定通过Cheese指针查看的CheeseCake对象,可以将它转换为Cake指针,因为CheeseCake都是!当然,即使在多重继承场景中,也不能通过指针将Cheese对象视为Cake。
答案 1 :(得分:0)
错误说明了一切,ERROR: Static cast from 'Cheese *' to 'Cake *', which are not related by inheritance, is not allowed
。尽管他们是兄弟姐妹,但他们并没有通过继承来解决。
如果你想制作芝士蛋糕,你可以做多重继承。
FOOD
/ \
CHEESE CAKE
\ /
CHEESECAKE
像这样:
class CheeseCake : public Cake, public Cheese