我有一个关于C++继承的非常基本的问题:
class A
{
public:
void foo() { print(); }
protected:
void print() {}
};
class B : public A
{
protected:
void print() { std::cout << "test" << std:: endl; }
};
Run Code Online (Sandbox Code Playgroud)
现在以下代码
B b;
b.foo();
Run Code Online (Sandbox Code Playgroud)
不打印任何东西,所以foo()显然没有调用新定义的print().这只能通过虚拟方法解决吗?
是的,你需要print虚拟以使其工作.否则,A::foo不知道后代可以提供print一个愉快的调用A版本的替代实现.编译器甚至可以在编译代码时内联print内部,使得实现完全无关紧要.fooAB
为了使派生类重写函数,必须virtual在基类中声明该函数。这意味着要调用的函数是在运行时根据对象的动态类型选择的。
如果在编译时知道每个对象的派生类型,则覆盖的替代方法是使用所谓的“好奇重复模板模式”(CRTP)将派生类型的知识注入基类(必须成为基类)。支持此的模板):
template <typename Derived> class A
{
public:
void foo() { static_cast<Derived*>(this)->print(); }
};
class B : public A<B>
{
private:
friend class A<B>; // assuming you don't want to make the function public
void print() { std::cout << "test" << std:: endl; }
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9730 次 |
| 最近记录: |