获取基类指针,但调用派生类函数
Create Function taking base class pointer but calling derived class function
我有两个类A
(base)和B
(衍生自A
):
class A { };
class B : public A
{
int data;
public:
int get_data() { return data; }
};
现在我有一个函数测试,它接受基类指针并调用派生类函数:
void test(A * ptr)
{
ptr->get_data();
}
但问题是ptr
可能指向A
的对象或B
的对象。如果指向B
的对象,则OK,但如果指向A
的对象,则有问题。
此外,我不想使get_data()
虚,因为data
不是A
的对象的属性。
如何检查ptr
是否指向B
的对象?我能想到的一个解决方案是dynamic_cast
,并检查NULL
。这是最好的解决方案还是我能有更好的解决方案?
这意味着您的test
函数在说谎。它说它将接受指向任何A
对象的指针,甚至是从A
派生的类型,但该函数实际上不会为B
以外的任何对象工作。你最好去做一个B*
:
void test(B* ptr)
{
ptr->get_data();
]
如果你可以改变A
和B
的接口(包括添加虚函数),如果你可以重新洗牌test
函数中的代码,你可以使用"访问者模式"。下面是使用Base
和Derived
类的示例:
class Visitor
{
public:
void Visit(Base * B)
{
}
void Visit(Derived * D)
{
int data = D->get_data();
}
};
class Base
{
public:
virtual void Accept(Visitor * V )
{
V->Visit(this);
}
};
class Derived: public Base
{
public:
int get_data()
{
return data;
}
virtual void Accept(Visitor * V )
{
V->Visit(this);
}
private:
int data;
};
通过这种方式,您可以遍历Base*
的向量,调用每个元素的Accept
,并且知道只有对于Derived
元素才会调用get_data
方法。
继承为is-a关系建模。很明显,在代码中B不是A,继承是错误的模型。你在评论中提到,你有一个矢量,它被传递给一个封闭的,更大的函数。我的建议是:
1. std::vector<boost::any>
2. std::vector<boost::variant<A,B>>
编辑下面是一个使用boost变量的例子:
class A
{
public:
void DoIt()
{
std::cout << "did it!" << "n";
}
};
class B
{
public:
void GetIt()
{
std::cout << "got it!" << "n";
}
};
typedef boost::variant<A,B> ab_t;
typedef std::vector<ab_t> list_ab;
void test(list_ab& list)
{
std::for_each(std::begin(list), std::end(list), [](ab_t& item)
{
if(A* a = boost::get<A>(&item))
a->DoIt();
if(B* b = boost::get<B>(&item))
b->GetIt();
});
}
你说实际上你有一个元素a或B的向量,那么你的测试函数实际上看起来像:
void test( A ** ptr )
然后你可以使用c++的重载功能来创建一个实用程序函数,正确的函数将被调用:
void test( A ** ptr ) {
A * elem;
int i=0;
elem = ptr[i++];
while(elem) {
testElement(elem);
elem = ptr[i++];
}
}
void testElement( A * ptr ) { }
void testElement( B * ptr ) {
ptr->get_data();
}
相关文章:
- 为什么使用 "this" 指针调用派生成员函数?
- 调用派生类成员函数
- 从基类实例调用派生类方法而不进行强制转换
- 从基类 (C++) 调用派生类中的非虚函数
- 在将派生类指针类型转换为派生类指针后,从基类指针调用派生类函数
- 如何从 Gtk::窗口调用派生对象的析构函数
- 在dynamic_pointer_cast后调用派生类的构造函数
- 从 Base 引用对象调用派生类的成员
- 有没有办法在没有虚拟的情况下使用基类指针调用派生类函数
- 在 c++ 中,如何使用向量调用派生类?
- C++通过 const 引用传递时不调用派生类函数
- 哪个基类调用派生重写的方法?
- 如何从包含基类指针的容器中调用派生类函数(基于其类型)?
- 如何调用派生类之一
- 从基类数组调用派生函数
- 从具有泛型返回类型的 crtp 基类调用派生类中的函数
- 基类如何调用派生类在 c++ 中传递的闭包?
- 通过在基类中虚拟调用派生类中的函数来访问派生类中的函数
- 如何在另一个类的向量中调用派生类的析构函数
- 通过reinterpret_casting方法指针从指针调用派生类的方法。这是 UB 吗?