你会在频繁运行的方法中使用动态强制转换吗?它有很大的开销吗?
究竟是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) 这个类是多态的.为什么两者都打印相同的输出?
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) 看下面的表达式:
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) 我正在用的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。
我使用动态模型来保证安全:
这是我用指针的代码:
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)
这段代码没有编译,但我想问有没有办法以类似的方式做到这一点.
关于这个问题有很多问题,但似乎没有人专门解决这个问题:鉴于代码库不允许用虚函数解决所有问题(正如你通常会做的那样),有一个函数:
/** 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是不切实际的.
编辑:在标题上添加问号,强调对可能性的怀疑
我最近遇到了强制转换和多重继承的问题:我需要转换为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 ++有点生锈,我不记得标准中的所有内容。
我有一个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吗?这样安全吗?我希望有更好的解决方案,但我别无选择。
我刚刚开始与一个团队合作,该团队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)