c++ 子类化一个类来改变一个内部类的虚函数,而不需要重新实现外部类

xn1cxnb4  于 2023-08-09  发布在  其他
关注(0)|答案(2)|浏览(111)

我发现了这个question,它询问如何覆盖嵌套类中的虚函数。然而,虽然回答,我仍然不明白如何实现这样的事情。

class Base {
public:
    class Nested {
        virtual void display() {
            std::cout << "Not overridden" << std::endl;
        }
    };
    
    /* tons of functionality which makes use of Nested and its methods */
};

字符串
以下面的代码为例:我想实现一个变体ImprovedBase,它只改变display函数的行为(理想情况下添加一些东西,然后调用原始实现),同时基本上保持从Base继承的功能完整**,而不重新实现Base的代码,它依赖于Nested**。
这个结构是库的一部分,所以我无法修改Base/Nested本身。
(How)我能实现这个吗?

e5njpo68

e5njpo681#

嵌套类通常带有许多未实现的期望。如果类不是嵌套的,它们通常会产生一些问题。
我不知道你为什么一开始就使用嵌套类,但让我们假设你不嵌套它们也没问题:

struct Nested {
    virtual void display() {
        std::cout << "Not overridden" << std::endl;
    }
};
  
struct Base {
    Nested example;
    void other_example(const Nested& n) { n.display(); }
};

字符串
如果只是关于重写Nested::display,你可以使用继承。从Nested派生的任何对象都可以传递给Base::other_example,并且可以自定义控制台输出。但是,继承对于“扩展”Nested成员的功能没有任何帮助。多态性需要指针或引用才能工作。
您可以将Base设置为模板,以轻松自定义其行为:

template <typename T>
struct Base {
    T example;
    void other_example(const T& n) { n.display(); }
};


这是否是一种可行的方法取决于是否需要将具有不同行为的Base处理为多态的(尽管即使这样,这也可能是一种方法)。虽然Base<Nested>与上面的相同,但您现在可以根据需要自定义T,例如:

struct Foo {
     void display() { std::cout << "Hello World\n"; }
 };


然后Base<Foo>是一个具有Foo成员的类,将Foo传递给Base<Foo>::other_example将在控制台上打印Hello World

lb3vh1jj

lb3vh1jj2#

不需要从Base继承来提供从Nested派生的类
您可以简单地执行以下操作:

class ImprovedNested : Base::Nested
{
    void display() override
    {
        Base::Nested::display();
        std::cout << "Overridden" << std::endl;
    }
};

字符串
现在,你必须提供你的版本,而不是原来的版本。而你不显示代码。
由于Nestedvirtual方法,因此通常/可能有方法传递我们的自定义版本。
比如:

class Base
{
private:
    std::unique_ptr<Nested> nested = std::make_unique<Nested>();
public:
    void setNested(std::unique_ptr<Nested> value) { nested = std::move(value); }

    // ...
};


您可以这样做:

Base base;
base.setNested(std::make_unique<ImprovedNested>());
// Use base normally now.

相关问题