提问人:Xaq 提问时间:2/20/2015 最后编辑:Xaq 更新时间:2/21/2015 访问量:806
C++ 从基类调用派生类中的函数,无需强制转换,也无需虚拟方法
C++ Call a function in a derived class from base class without casting and no virtual methods
问:
我最近在一次采访中被问到这个问题:
#include <iostream>
class Base
{
public:
void foo() { std::cout << "foo" << std::endl; }
};
class Derived : public Base
{
public:
void bar() { std::cout << "bar" << std::endl; }
};
int main(int argc, const char *argv[])
{
Base *p = new Derived;
// additional code here
return 0;
}
问题的条件是不能更改 Base 类和 Derived 类(例如,更改方法的名称、添加其他方法或将方法更改为 virtual)。 进一步的限制是不能使用任何类型的铸件。 必须使用指针 p。 除此之外,您可以编写任何其他代码,包括尽可能多的类,以确保使用 p 指向的对象调用“bar()”方法。
鉴于不允许演员阵容,我唯一能想到的是一个老派的:
Derived *d;
memcpy(&d, &p, sizeof p);
d->bar();
这甚至比石膏还要糟糕。 面试官斥责我,告诉我我甚至没有最基本的对象层次结构知识,因为我看不到这个问题的非常明显、微不足道的解决方案。
如果这个问题是重复的,我深表歉意;我见过关于从基类访问派生类中的方法的其他问题,但在我看到的所有情况下,答案都涉及对任何一个类的强制转换或修改。
他可能是对的;我已经用 C++ 编程超过 15 年了,但我看不到解决方案。可能是我从未遇到过它,因为我在这种情况下会使用强制转换:在这种情况下,它必须是一个static_cast,因为没有虚拟方法(甚至没有析构函数)可以允许dynamic_vast编译(它失败并显示一条消息:“'Base' is not a polymorphic type”
答:
简单易行:
#define Base Derived
就在.(然后你可以调用它)main
bar
评论
答案可能是:这不会编译。
评论
必须使用指针 p。除此之外,您可以编写任何其他代码,包括尽可能多的类,以确保使用 p 指向的对象调用“bar()”方法。
你说,有多少节课?
#include <iostream>
class Base
{
public:
void foo() { std::cout << "foo" << std::endl; }
};
class Derived : public Base
{
public:
void bar() { std::cout << "bar" << std::endl; }
};
int main()
{
class Base
{
public:
void bar() { std::cout << "bar" << std::endl; }
};
class Derived : public Base
{
};
Base *p = new Derived;
p->bar();
}
评论
#define Base Derived
class Derived : public Base
您可以使用 for type-punning:union
union {
Base* bp;
Derived* dp;
} my_union = {p};
my_union.dp->bar();
评论
我可能会想出这样的东西:
void foobar(Base* b){
Derived d;
d.bar();
}
int main(int argc, const char *argv[]){
Base *p = new Derived;
foobar(p);
return 0;
}
如果面试官抱怨这太笨拙了,我会请他少问一些古怪的问题:P
不,真的,我确实认为这是对一个相当学术问题的有效回答。我正在使用 p 指向的对象(调用 foobar 函数)并确保调用了“bar()”。我不认为这样的练习值得一个更复杂的解决方案。从逻辑上讲,我的解决方案无法与面试官想到的任何解决方案区分开来。
评论