按成员值强制转换
Cast by member value
根据对象实例的成员值强制转换对象实例时遇到问题。测试用例:
class base {
public:
virtual int type() const = 0;
};
class derived : public base {
public:
virtual int type() const { return 1; }
virtual void derivedspecific() {}
};
int main() {
base* test = new derived;
(test->type()==1?((derived*)test):NULL)->derivedspecific();
}
想象一下,我们在三元运算符中有数百个子类和数百个case,它们都是在宏中编写的。我应该如何解决这个问题?如果我在三元运算符中放入更多的事例,我会得到错误"不同指针类型之间的条件表达式"。是的,测试变量需要是一个基类指针。这只是一个简短的例子。
首先,您的derivedspecific
不需要是病毒的,因为看起来您不需要通过指向基类的指针来调用它。我假设派生类中的名称总是不同的。否则,如果derivedspecific
总是相同的名称和签名,则实际上不需要type()
:
class base
{
public:
virtual int doWork() const = 0;
};
class derived : public base
{
public:
virtual void doWork() { /* do your work here*/ }
};
int main()
{
base* test = new derived;
test->doWork();
}
NULL->derivedspecific()
不会编译((derived*)NULL)->derivedspecific()
是未定义的行为(大多数平台上的分段故障
有一种机制是专门为支持这种行为而设计的,即dynamic_cast
,它类似于:
#include <typeinfo>
class base
{
public:
virtual ~base(){};
};
class derived1 : public base
{
public:
void derived1specific() const {}
};
class derived2 : public base
{
public:
void derived2specific() const {}
};
int main()
{
// use pointers
base* test = new derived1;
derived2* d2 = dynamic_cast<derived2*>(test);
if(d2)
d2->derived2specific();
derived1* d1 = dynamic_cast<derived1*>(test);
if(d1)
d1->derived1specific();
// or simply
if(derived1* d1 = dynamic_cast<derived1*>(test) )
d1->derived1specific();
else if(derived2* d2 = dynamic_cast<derived2*>(test))
d2->derived2specific();
// use references
const base& testr = derived1();
try{
const derived1& d1 = dynamic_cast<const derived1&>(testr);
d1.derived1specific();
}
catch(std::bad_cast&){}
try{
const derived2& d2 = dynamic_cast<const derived2&>(testr);
d2.derived2specific();
}
catch(std::bad_cast&){}
}
你想做的事情,我不建议你,是这样的:
auto doNothing = [](){return;};
(test->type()==1?(((derived1*)test)->derived1specific()):doNothing());
你可以在这里尝试完整的代码。
至于你的评论:你可以用一个免费的函数代替宏(无论如何都是可取的)
void derived1specific(base* b){
if(derived1* d1 = dynamic_cast<derived1*>(b))
d1->derived1specific();
}
它正是你的代码想要做的:当且仅当它合适时,执行派生的特定函数;你可以简单地称之为:
derived1specific(test);
为此,请使用开关:
Base * test = //something returning a Base *
switch(test)
{
case 0 :
static_cast<Derived0*>(test)/*[...]*/;
break;
case 1 :
static_cast<Derived1*>(test)/*[...]*/;
break;
//...
}
如果只有一个类返回相同的type(),那么,您可以使用static_cast,因为您确信这一点。
相关文章:
- 从成员指针到整个结构/类的强制转换
- 将方法转换为调用该方法的成员函子对象会导致崩溃
- 从类成员函数到类 C 函数指针的转换
- 静态成员变量不会由 gettext 转换
- 指针类型类成员的动态强制转换的恒定性是什么?
- 虚拟成员函数的定义是否强制在同一转换单元中动态初始化静态数据成员?
- 转换模板中的成员函数指针
- 传递可变参数时在成员初始值设定项列表中强制转换
- 将函数强制转换为成员函数
- 返回对常量结构(指针类型)成员的引用:明显的左值到右值转换
- 指向类成员函数的指针中存在类型转换错误
- 在不复制数据的情况下,将double数组转换为只有double成员的structs数组
- 为什么不能指向指针,在没有强制转换的情况下访问结构成员?
- 将结构C++成员从非常量转换为常量
- C++:易失性实例中的易失性成员函数 - 将数组分配给指针是无效的转换?
- 返回带有另一个类的数据成员的构造函数?遇到转换错误?
- 如何将任何值转换为对象并使用 boost::p roperty_tree json 添加成员
- 虚拟地将结构向量转换为结构成员的向量
- 为create_pthread()调用强制转换成员函数
- 转换成员函数指针