LLVM拥有自己的RTTI替代方案,这是对内置RTTI的速度提升,并允许动态转换为没有vtable(dyn_cast)的类.但是,它仍然可以完全按照使用的方式dynamic_cast<>使用,尽管它允许它与更多类一起使用.
LLVM是一个声誉良好的C++项目,所以这似乎是在面对一个普遍的说法,即太多的动态转换是设计糟糕的标志,也被称为代码气味.当然,性能更好的动态模型无法改善其在设计中的使用,而不是标准dynamic_cast.那么谁在这里?在C++代码中,是否存在大规模使用动态铸造是一个很好的设计选择的情况?谷歌在LLVM中继源代码中出现了690次这种动态转换.
基本上我只想使用任意类型的给定参数进行任意操作.
参数类型基类是Var,而Operation是将为给定参数执行的操作的基类.
我有Evaluator类,它包含使用opId映射的运算符集合.Evaluator将根据evaluate()成员函数中给出的opId参数进行操作,然后evaluate()函数将搜索将接受参数类型和opId的受支持运算符.
我想问的是,有没有有效的模式或算法可以在没有dynamic_cast <>和/或循环运算符集合的情况下执行此操作.
`
class Var {
public:
bool isValidVar();
static Var invalidVar();
}
template<typename T> class VarT : public Var {
public:
virtual const T getValue() const;
}
class Operator {
public:
virtual Var evaluate(const Var& a, const Var& b) = 0;
}
template<typename T> class AddOperator : public Operator {
public:
virtual Var evaluate(const Var& a, const Var& b)
{ //dynamic_cast is slow!
const VarT<T>* varA = dynamic_cast<const VarT<T>*>(&a);
const …Run Code Online (Sandbox Code Playgroud) 类型检查仅仅是整数比较吗?或者有一个是否有意义GetTypeId虚拟函数来区分哪个会使它成为整数比较?
(只是不希望事物成为类名的字符串比较)
编辑:我的意思是,如果我经常期待错误的类型,使用类似的东西是否有意义:
struct Token
{
enum {
AND,
OR,
IF
};
virtual std::size_t GetTokenId() = 0;
};
struct AndToken : public Token
{
std::size_t GetTokenId() { return AND; }
};
Run Code Online (Sandbox Code Playgroud)
并使用该GetTokenId成员而不是依赖dynamic_cast.
我发现dynamic_cast在我期望它的情况下不起作用,并且typeid在运行时查看对象使得情况更加清晰.我只想要从基础到派生的演员,我无法弄清楚为什么它不起作用.
我有一个这样的类结构:
class BoundaryCondition {
public:
virtual void DoSomething() = 0;
virtual ~BoundaryCondition() { /* * */ }
}
class ReflectingBc : BoundaryCondition {
public:
virtual void DoSomething();
}
class MarshakBc : BoundaryCondition {
public:
virtual void DoSomething();
MarshakBc(double value);
void changeValueLaterOn(double value);
private:
double value_;
}
Run Code Online (Sandbox Code Playgroud)
我(基本上)有一个std::vector<BoundaryCondition*>代表问题部分边界条件的东西.我希望能够接受它,vector并且对于其中的所有MarshakBc对象,请致电changeValueLaterOn.所以我有一个看起来像的循环
for (std::vector<BoundaryCondition*>::iterator bc = bcPtrs_.begin();
bc != bcPtrs_.end(); ++bc)
{
if (std::string(typeid(MarshakBc).name()) == std::string(typeid(**bc).name()) )
{
std::cerr << "SAME! "; …Run Code Online (Sandbox Code Playgroud) 这个问题与这个问题非常相似为什么我不能在多重继承期间"动态地"广播"侧身"?,除了强制转换确实有效 - 只是不在构造函数内部.
标题:
class A
{
public:
virtual ~A() {}
void printA();
};
class B
{
public:
B();
virtual ~B() {}
void printB();
private:
std::string message_;
};
class C : public A, public B
{
public:
C() {}
virtual ~C() {}
};
Run Code Online (Sandbox Code Playgroud)
资源:
void A::printA() { cout << "A" << endl; }
B::B()
{
A* a = dynamic_cast< A* >( this );
if ( a ) {
message_ = std::string( "A and B" );
} else { …Run Code Online (Sandbox Code Playgroud) void foo(MyClass* myClass)
{
BaseClass* pBaseClass = dynamic_cast<BaseClass*>(myClass);
delete myClass; // <-------------- Does this affects on pBaseClass ?
}
Run Code Online (Sandbox Code Playgroud)
总的来说dynamic_cast实际上有多少?(它是否像复制构造函数一样工作?)
我们可以使用多态(继承+虚函数)来概括公共基类型下的不同类型,然后引用不同的对象,就好像它们属于同一类型一样.
使用dynamic_cast似乎是完全相反的方法,因为本质上我们在决定我们想要采取什么操作之前检查对象的特定类型.
有没有任何已知的例子可以像传统的多态一样容易实现dynamic_cast?
使用auto和dynamic_cast时,我遇到了一个非常奇怪的行为.这是我有的课程:
class BaseInterface {
public:
virtual void someMethod()=0;
};
class Derived:public BaseInterface {
public:
virtual void someMethod1()=0;
void someMethod()override;
};
Run Code Online (Sandbox Code Playgroud)
当然,有一些类实现了所有派生方法.
然后有第三个类看起来像这样:
class ThirdClass {
public:
void demoMethod(BaseInterface&);
void anotherMethod(Derived&);
};
void ThirdClass::demoMethod(BaseInterface& obj) {
auto buffer=dynamic_cast<Derived&>(obj);
anotherMethod(buffer);
}
Run Code Online (Sandbox Code Playgroud)
当我用gcc编译它时,我得到一个"无法分配抽象类型的对象"错误.而当我更换
auto buffer=...
Run Code Online (Sandbox Code Playgroud)
同
Derived& buffer=...
Run Code Online (Sandbox Code Playgroud)
一切都很好.为什么会这样?自动没有推断出正确的类型或什么?
我还发现了一个仍然使用auto的肮脏技巧:
void ThirdClass::demoMethod(Base& obj) {
auto buffer=dynamic_cast<Derived*>(&obj);
anotherMethod(*buffer);
}
Run Code Online (Sandbox Code Playgroud) 我的问题是:我有一个接口根类,有几个具体的分支类.在应用程序代码中,存在一个指向根类的指针向量.我需要在几个地方循环遍历向量中的所有元素,并将它们与给定实例进行比较:
// Application Code
void compare_loop(Root *r, std::vector<Root*> vec) {
for (auto v : vec) {
if (r->compare(v)) {
// Do something to v
}
}
}
Run Code Online (Sandbox Code Playgroud)
我最初的方法是在Root类中"比较"一个虚函数:
// Class Definition
class Root {
public:
Root(double bar) : Bar(bar) {};
virtual bool compare(Root *r) = 0;
protected:
double Bar;
};
class BranchA : public Root {
public:
BranchA(double bar, double baz) : Root(bar), BazA(baz) {};
bool compare(Root *r) override;
protected:
double BazA;
};
class BranchB : public Root {
public: …Run Code Online (Sandbox Code Playgroud) class BASE {
public:
virtual ~BASE() {}
void lamp() {
cout << "\nBASE CLASS";
}
};
class DERIVED : public BASE {
public:
void fun();
};
void DERIVED::fun() {
cout << "\nDERIVED CLASS!";
}
int main() {
BASE * pbase = new DERIVED; //BASE CLASS POINTER
void * vbase = pbase; //VOID POINTER TAKING BASE POINTER
DERIVED * pder; //DERIVED CLASS POINTER
//pder = static_cast<DERIVED *>(vbase); //THIS WORKS
pder = dynamic_cast<DERIVED *>(vbase); //THIS DOESN'T
pder->lamp();
pder->fun();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
每当我尝试将 …
c++ ×10
dynamic-cast ×10
auto ×1
c++11 ×1
casting ×1
constructor ×1
llvm ×1
pointers ×1
polymorphism ×1
reference ×1
this ×1
typeid ×1