标签: dynamic-cast

两个dynamic_cast问题

  1. 你会在频繁运行的方法中使用动态强制转换吗?它有很大的开销吗?

  2. 究竟是dynamic_cast返回的指针是什么.指向同一地址的指针?指向不同实例的指针?我缺乏这种理解.更具体 - 只有在运行时它被证明是一个指向子类型的指针时,我希望对父类型的指针进行赋值.解决方案?

谢谢.

c++ dynamic-cast

2
推荐指数
1
解决办法
891
查看次数

带有模板类的dynamic_cast"dynamic_cast的无效目标类型"

在模板类中,我试图使用dynamic_cast从文件中读取字符串,并希望能够使用bad_cast异常捕获失败的强制转换.但是,在编译时(将测试程序设置为double作为模板类,我得到了dynamic_cast的这个错误:

datafilereader.cpp(20): error C2680: 'double *' : invalid target type for dynamic_cast
Run Code Online (Sandbox Code Playgroud)

我试着把它写成<T>而不是<T*>(当我看到关于动态演员的其他问题时,后者似乎是常见的方式......),但实际上是同样的错误.

DataFileReader.cpp

#include "DataFileReader.h"
#include <typeinfo>

template <typename T>
void DataFileReader<T>::openFiles() {
    dataFileStream.open(dataFileName);
    errorFileStream.open(errorFileName, ios::app);
    if (!(dataFileStream.is_open() && errorFileStream.is_open()))
            throw(runtime_error("Couldn't open at least one of the files."));
}

template <typename T>
bool DataFileReader<T>::readNextValue(T &aValue) {
    ios_base::iostate mask = ios::eofbit|ios::failbit|ios::badbit;
    dataFileStream.exceptions(mask);
    while (true) {
        string readValue;
        try {
            dataFileStream >> readValue;
            aValue = dynamic_cast<T*>(readValue);
            return true;
        }
        catch(bad_cast &bc) {
            errorFileStream << readValue << " …
Run Code Online (Sandbox Code Playgroud)

c++ dynamic-cast

2
推荐指数
1
解决办法
4482
查看次数

静态和动态演员之间的区别

这个类是多态的.为什么两者都打印相同的输出?

class A
{
public:
    virtual void P(){ cout << "A" << endl; }

};
class B : public A
{
public:
    void P()override{
        cout << "B" << endl;
    }
    B(){ cout << "Created B" << endl; s = "Created by B"; }
    string s;
};
Run Code Online (Sandbox Code Playgroud)

主要:变体1:

A* a = new B();    // Created B
B* b = static_cast<B*>(a);
b->P();    B
cout<<b->s<<endl;  // Created by B
Run Code Online (Sandbox Code Playgroud)

变种2:

A* a = new B();
    B* b = dynamic_cast<B*>(a);
    if (b){
        b->P();
        cout …
Run Code Online (Sandbox Code Playgroud)

c++ dynamic-cast static-cast

2
推荐指数
1
解决办法
8794
查看次数

动态铸造需要目标类型吗?

看下面的表达式:

Target * p = dynamic_cast<Target*>(pFarAncestor);
Run Code Online (Sandbox Code Playgroud)

是否存在动态转换类型可能与左值(本例中为p)类型不同的情况?换句话说,有一个原因,一直是显式目标变量的类型?

我想知道为什么编译器不接受如下的签约形式:

Target * p = dynamic_cast<>(pFarAncestor);
Run Code Online (Sandbox Code Playgroud)

甚至

Target * p = dynamic_cast(pFarAncestor); // ok this seems a function call indeed
Run Code Online (Sandbox Code Playgroud)

c++ dynamic-cast

2
推荐指数
1
解决办法
94
查看次数

为什么在使用 memset 用零填充对象后,在 dynamic_cast 时出现异常

我正在用的dynamic_cast这个奇怪的运行时异常,但只有当我填的是我与使用零铸造的对象memset,或者只是一些数据复制到它memcpy。这是生成异常的示例。

class Base
{
public:
    virtual void func() { }
};

class Derived : public Base
{
public: 
    void func() override { }    
};

int main()
{   
    Derived derived;
    Base* base_ptr = &derived;
    memset(base_ptr, 0, sizeof(Derived));

    Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);    
}
Run Code Online (Sandbox Code Playgroud)

异常消息是:在此处输入图片说明

如果我Derived使用 memcpy将一个对象复制到另一个对象,我会得到相同的异常。任何人都知道发生了什么,是否弄乱了dynamic_cast使用的 RTTI ?

我正在制作一个游戏引擎,它是一个实体组件系统,在程序中的某个时刻,我从一个文件中加载了所有对象及其组件。我实现不同组件的方式是使用继承(每个组件都源自一个基本组件)。当我加载对象及其组件时,我不能只分配组件占用的内存量,我必须使用新的组件名称,因为只有这样 dynamic_cast 才能工作。

我正在使用 Visual Studio 2019。

c++ inheritance dynamic-cast memset memcpy

2
推荐指数
1
解决办法
76
查看次数

动态转换为引用

我使用动态模型来保证安全:

这是我用指针的代码:

XYZ xyz = dynamic_cast<XYZ*>(abc);
if (xyz == nullptr)
{
    // TODO handle error
}
Run Code Online (Sandbox Code Playgroud)

现在有办法做同样的事情,但有参考:

XYZ& xyz = dynamic_cast<XYZ&>(abc);
if (xyz == nullptr)
{
    // TODO handle error
}
Run Code Online (Sandbox Code Playgroud)

这段代码没有编译,但我想问有没有办法以类似的方式做到这一点.

c++ dynamic-cast reference-type

1
推荐指数
1
解决办法
634
查看次数

没有强制转换的dynamic_cast类型检查功能?

关于这个问题有很多问题,但似乎没有人专门解决这个问题:鉴于代码库不允许用虚函数解决所有问题(正如你通常会做的那样),有一个函数:

/** Check if obj is a T, including base classes. */
template <class T>
inline bool is_a(const basic &obj)
{
    return dynamic_cast<const T *>(&obj) != 0;
}
Run Code Online (Sandbox Code Playgroud)

但显然演员即使没必要也会制作.如何编写此函数以仅检查,即使用dynamic_cast功能而不进行实际演员?假设用虚函数替换对此函数的调用,或为此目的实现穷人的RTTI是不切实际的.

编辑:在标题上添加问号,强调对可能性的怀疑

c++ dynamic-cast rtti

1
推荐指数
1
解决办法
997
查看次数

多重继承转换不按预期工作

我最近遇到了强制转换和多重继承的问题:我需要转换为Base*to Unrelated*,因为特定的Derived类派生了Unrelated类.

这是一个简短的例子:

#include <iostream>

struct Base{
    virtual ~Base() = default; 
};

struct Unrelated{
    float test = 111;    
};

struct Derived : Base,Unrelated{};

int main(){
    Base* b = new Derived;
    Unrelated* u1 = (Unrelated*)b;
    std::cout << u1->test << std::endl; //outputs garbage
    Unrelated* y = dynamic_cast<Unrelated*>(b);
    std::cout << y->test << std::endl; //outputs 111
}
Run Code Online (Sandbox Code Playgroud)

第一个演员显然不起作用,但第二个演员确实有效.我的问题是:为什么第二次演员工作?难道dynamic_cast只适合投射到相关的类类型吗?我认为Unrelated在运行时没有任何关于它的信息,因为它不是多态的.

编辑:我使用colirus gcc作为示例.

c++ dynamic-cast multiple-inheritance reinterpret-cast

1
推荐指数
2
解决办法
559
查看次数

将类型动态转换为类型的安全方法?

我的C ++有点生锈,我不记得标准中的所有内容。

我有一个void*。在一个特定的函数中,它要么是继承Alpha的类,要么是继承Beta的类。这两个基类都具有虚函数。但是我似乎无法分辨哪个是哪个

class Alpha {
public:
    virtual void Speak() { printf("A"); }
};
class Beta {
public:
    virtual void Speak() { printf("B"); }
};
int main(){
    //BAD CODE WILL PRINT TWICE
    void *p = new Alpha;
    Alpha*a = dynamic_cast<Alpha*>((Alpha*)p);
    Beta*b = dynamic_cast<Beta*>((Beta*)p);
    if(a)
        a->Speak();
    if(b)
        b->Speak();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我如何弄清楚哪个班级是哪个班级?此代码库中有100多个类,它们被转换为void。他们中的大多数继承了5个基类,但是我不急于发现。class Dummy {public: virtual void NoOp(){}};在使用动态投射之前,唯一的解决方案是从类似对象继承并投射到Dummy吗?这样安全吗?我希望有更好的解决方案,但我别无选择。

c++ dynamic-cast

1
推荐指数
1
解决办法
112
查看次数

为什么在某些情况下reinterpret_cast有效,而在另一些情况下无效?

我刚刚开始与一个团队合作,该团队reinterpret_cast显然应该在适当的时候使用它dynamic_cast。尽管他们使用reinterpret_cast的代码似乎仍然可以正常工作,所以我决定将其搁置一旁,直到最近它最终停止工作为止。

struct Base {
 virtual void do_work() = 0;
};
struct D1 : public Base {
 virtual void do_work();
 std::vector<int> i;
};

struct D2: public D1 { 
 void do_work()
};

struct Holds_data {
    std::vector<int> i;
};
struct Use_data : public Holds_data {
 virtual void do_work();
};


struct A : public Use_data, public Base {
    void do_work();
};

//case 1
// this code works
Base* working = new D2();
D2*   d2_inst = reinterpret_cast<D2*>(working);


//case 2 …
Run Code Online (Sandbox Code Playgroud)

c++ dynamic-cast reinterpret-cast

1
推荐指数
1
解决办法
147
查看次数