Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop &引用;“交叉浇铸”;尝试使用静态强制转换失败;为什么?_Oop_C++11_Polymorphism_Dynamic Cast_Static Cast - Fatal编程技术网

Oop &引用;“交叉浇铸”;尝试使用静态强制转换失败;为什么?

Oop &引用;“交叉浇铸”;尝试使用静态强制转换失败;为什么?,oop,c++11,polymorphism,dynamic-cast,static-cast,Oop,C++11,Polymorphism,Dynamic Cast,Static Cast,为什么“交叉投射”不起作用 以下内容将创建此对象继承模型: FOOD / \ CHEESE CAKE 在这里,我尝试从cheese到cake的static\u投射一个指针,生成一个cheesecake:D。我从Apple-Clang/LLVM得到以下错误: 但他们是有遗传关系的:他们是兄弟姐妹 为什么我不能将奶酪转换成蛋糕,就像我将int转换成浮点?为什么我不能从继承自同一基类的派生对象“交叉转换” 下面是最小、完整且可验证的示例,包括静态_-cast和动态_-ca

为什么“交叉投射”不起作用

以下内容将创建此对象继承模型:

     FOOD
    /    \
 CHEESE  CAKE
在这里,我尝试从
cheese
cake
static\u投射一个指针,生成一个cheesecake:D。我从Apple-Clang/LLVM得到以下错误:

但他们是有遗传关系的:他们是兄弟姐妹

为什么我不能将
奶酪
转换成
蛋糕
,就像我将
int
转换成
浮点
?为什么我不能从继承自同一基类的派生对象“交叉转换”

下面是最小、完整且可验证的示例,包括
静态_-cast
动态_-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;
}
#包括
#包括
等级食品{
公众:
食品(标准:串品牌):品牌{
虚拟~Food(){};
std::string brand(){返回品牌}
虚空切割()常量{std::cout“蛋糕切割”。指针重新分配和向下转换工作正常。
奶酪蛋糕=动态铸造(食品);
奶酪蛋糕_ptr->cut();//->“蛋糕切”。同样,食物*动态地浇铸在奶酪上*
/*~~~注意:以下示例故意抛出错误~~~*/
/*
动态交叉播放尝试:
错误:从不兼容类型“Cake*”分配给“Cheese*”
动态演员阵容:没有意义,因为奶酪和蛋糕之间的关系不是多态的
*/
cheeseCake_ptr=动态铸造(cheese_ptr);
奶酪蛋糕->切();
/*
静态交叉播放尝试:
错误:不允许从“Cheese*”到“Cake*”的静态强制转换,这与继承无关
静态强制转换:为什么不起作用?我们知道数据类型。
*/
奶酪_ptr=&c;
蛋糕_ptr=&cc;
cheeseCake_ptr=静态铸造(cheese_ptr);

std::cout这个错误说明了一切,
错误:不允许从“Cheese*”到“Cake*”的静态转换,这与继承无关
。即使它们是兄弟,也与继承无关

    FOOD
   /    \
CHEESE   CAKE
   \     /
  CHEESECAKE
如果你绝对想做奶酪蛋糕,你可以做多重继承

    FOOD
   /    \
CHEESE   CAKE
   \     /
  CHEESECAKE
像这样:

class CheeseCake : public Cake, public Cheese

与继承无关
意味着在同一分支上

您不应该将强制转换值误认为是强制转换指针(反之亦然),它们是不同的类型转换

int
to
float
使用一个函数将给定类型的值转换为目标类型的值(请注意,此函数可以是显式的,也可以是隐式的,对于特定情况,即在语言中定义的情况,它是隐式的)在C++中,您可以通过实现类类的cTor来接收自定义类的类型,或者通过实现类B的CAST运算符来返回类型A值/p>的值。
Cake*
Cheese*
不会转换值,但会尝试以不同的方式查看给定对象。这是子类型多态性(因此需要使用
dynamic\u cast
)。给定类型层次结构,可以轻松查看(不转换)Cheese对象作为食物对象,使用食物指针指向奶酪对象(就像不同的人对你的看法不同一样,(想想朋友、教授或医生在你始终是同一个人时理解你的方式!)。这很清楚(至少在你的层次结构中)奶酪不能被视为蛋糕,如果奶酪对象对蛋糕的特定方法有什么反应的话?你是动物,也是狗,但很难想象我能把你看作狗(你没有4条腿,不是吗

不要被你的情况所欺骗。看起来奶酪和蛋糕的内容是一样的,但是给定的层次结构告诉了真相:没有同一个分支,你不能从蛋糕指针中得到奶酪指针。C++编译器保护你不受此影响。
现在,如果您使用多重继承,例如从Cheese和Cake继承的CheeseCake,情况会有轻微的变化。然后给定一个通过Cheese指针查看的CheeseCake对象,可以将其转换为Cake指针,因为CheeseCake两者都是!当然,即使在多重继承场景中,Cheese对象也不能被视为蛋糕通过指针。

但由于遗传不是虚拟的,因此热量是原来的两倍:(我不想把两者结合起来做成奶酪蛋糕;我想把奶酪蛋糕称为
cake
对象,而不是
cheese
对象。回想起来,我意识到这是一个有点令人困惑的例子。但是,对于铸造值来说,相同的逻辑不成立吗?假设我们将浮点值转换为int。现在,我们可以截断int上的小数吗?Ret求分数部分,找到它的上限或下限?不!在从float到int的转换后,这些都没有意义…但我们仍然这样做。我告诉过你,当转换值时,你将类型转换为另一个类型。使用指针时,没有转换!在值转换中,你有两个值,原始值和转换后的值函数。在指针投射中,始终有一个对象,但有两个视图(指针是对象上的视图),根本没有转换(我可以将您视为OP,您的一些朋友将您视为足球运动员,同一个人,两个不同的视图,没有值转换,只有与您交互的不同方式)。