简体   繁体   English

有没有办法将 object 动态更改为另一种类型?

[英]Is there a way to dynamically change an object to another type?

Let's say I have a class A that inherits from its parent class B, and there is another class C that also inherits from class B. Is there a way to change this pointer of class A to class C at run time? Let's say I have a class A that inherits from its parent class B, and there is another class C that also inherits from class B. Is there a way to change this pointer of class A to class C at run time?

class A : public B {
    A::someFunction() {
        //can I change this pointer to class C here?
    }
}

class C : public B {
    ...
}

You cant and you shouldn't.你不能也不应该。 The reason is pretty simple.原因很简单。 Take a look at this code,看看这段代码,

class Base {
public:
    Base() {}

    virtual void SayHello() {}
};

class A_Derived : public Base {
public:
    A_Derived() {}

    virtual void SayHello() override { ... }
    void SayAllo() { ... }
};

class B_Derived : public Base {
public:
    B_Derived() {}

    virtual void SayHello() override { ... }
    void SayBello() { ... }
};

Now when is we assign the A_Derived class pointer to B_Derived , the compiler will allow to call the SayBello method.现在我们何时将A_Derived class 指针分配给B_Derived ,编译器将允许调用SayBello方法。 This is because for the compiler, its a B_Derived class pointer, it doesn't know about the actual pointer data is pointing at a data block of A_Derived (because inheritance is not compile time, its runtime).这是因为对于编译器,它的B_Derived class 指针,它不知道实际的指针数据指向A_Derived的数据块(因为 inheritance 不是编译时,它的运行时)。 So what happens when you call SayBello using that pointer?那么当您使用该指针调用SayBello时会发生什么? Its gonna be undefined behavior.这将是未定义的行为。 You see the issue?你看到问题了吗?

This is why you cant do it (logically and also using C++ style casting).这就是为什么你不能这样做(逻辑上也使用 C++ 样式转换)。

Is there a way to dynamically change an object to another type?有没有办法将 object 动态更改为另一种类型?

No. The type of an object cannot change through its lifetime.不可以。object 的类型在其生命周期内不能改变。

Let's say I have a class A that inherits from its parent class B, and there is another class C that also inherits from class B. Is there a way to change this pointer of class A to class C at run time? Let's say I have a class A that inherits from its parent class B, and there is another class C that also inherits from class B. Is there a way to change this pointer of class A to class C at run time?

No.不。

At best, you could destroy the original object, and reuse its memory to create another object.充其量,您可以破坏原来的 object,并重新使用它的 memory 来创建另一个 object。 Obviously the size and alignment of the memory must be sufficient for the new type.显然,memory 的尺寸和 alignment 必须足够新的类型。 Any reference (which includes pointers such as this in a member function) to the old object will have been invalidated by the destruction of the original object.对旧 object 的任何引用(包括成员函数中的this等指针)都将因原始 object 的破坏而失效。 Reuse of storage is an advanced topic which I don't recommend to beginners.存储的重用是一个高级主题,我不向初学者推荐。

There is no valid way to do this for one simple reason - in your class inheritance structure, an object of class A cannot be also an object of class C . There is no valid way to do this for one simple reason - in your class inheritance structure, an object of class A cannot be also an object of class C . In C++, two objects of different types can have the same address if and only if one of the objects is a subobject of the other, which is not your case.在 C++ 中,当且仅当其中一个对象是另一个对象的子对象时,两个不同类型的对象可以具有相同的地址,这不是您的情况。 If you cast a pointer to A to a pointer to C , the pointer will still refer to an object of type A , and dereferencing the casted pointer would result in undefined behavior.如果将指向A的指针强制转换为指向C的指针,则该指针仍将引用A类型的 object ,并且取消引用强制转换的指针将导致未定义的行为。

Most probably, what you want to do is to create an object of class C from an object of class A . Most probably, what you want to do is to create an object of class C from an object of class A . You can use a converting constructor or a conversion operator to implement this.您可以使用转换构造函数转换运算符来实现这一点。

Note that if what you really want is to reuse the storage allocated for the object of type A , you will still need to destroy the object A first and then construct the object C . Note that if what you really want is to reuse the storage allocated for the object of type A , you will still need to destroy the object A first and then construct the object C . You will have to save any relevant data from A before destroying it to be able to construct C with the data.您必须在销毁A之前保存 A 中的任何相关数据,以便能够使用该数据构建C

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

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