繁体   English   中英

纯虚拟会员有什么好处(除了他们可能防止的人为错误)?

[英]Are there any advantages to pure virtual members (except the human error that they might prevent)?

我有一堆具有纯虚拟成员的类,它将由派生的非抽象类填充。 我收到错误:

Error   C2259   'ABC': cannot instantiate abstract class    TEMP    c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.16.27023\include\xmemory0   879 

这个错误可以通过使用stack<ABC*>来解决,但是堆 memory 访问比堆栈 memory 慢,所以我正在考虑重写基础 class ABC 没有纯虚拟成员。

这样做会有什么缺点吗(除了可能使用此代码的人的人为错误)?

有没有办法可以在堆栈上创建具有纯虚拟成员的类堆栈? 或者,也许,我对使用堆太偏执了? class(在原始代码中)将被非常频繁地访问。

以下代码的简化版本:

#include <iostream>
#include <stack>

class ABC {
public:
    ABC(int& a) : m_a(a) {}
    ~ABC() {}
    virtual void do_something() = 0;
    int m_a;
};

class DEF : public ABC {
public:
    DEF(int& a) : ABC(a) {}
    void do_something() override;
    ~DEF() {}
};

void DEF::do_something() {
    std::cout << "Hi!\n";
}

int main(int argc, char* argv[]) {
    int x = 123;
    std::stack<ABC> s;

    s.push(DEF(x));
}

在这次通话中

s.push(DEF(x));

DEF类型的临时 object 被隐式转换为ABC类型的 object 。 因此,如果调用虚拟 function 则将调用 class ABC 的虚拟 function。

使用指针或引用时可以使用多态性。

这是您更新的程序。

#include <iostream>
#include <stack>

class ABC {
public:
    ABC(int& a) : m_a(a) {}
    ~ABC() {}
    virtual void do_something() 
    {
        std::cout << "Bye!\n";
    };
    int m_a;
};

class DEF : public ABC {
public:
    DEF(int& a) : ABC(a) {}
    void do_something() override;
    ~DEF() {}
};

void DEF::do_something() {
    std::cout << "Hi!\n";
}

int main()
{
    int x = 123;
    std::stack<ABC> s;

    s.push(DEF(x));

    s.top().do_something();
}

程序 output 是

Bye!

如您所见,有 object 切片。

请注意,您需要将析构函数设为虚拟。 你可以写在基础 class

virtual ~ABC() = default;

您根本不能拥有具有虚拟成员(纯或非纯)的对象的容器(其中的堆栈是一个示例)并保持动态行为。 您可以拥有指向此类对象的指针容器并维护动态行为,但不能维护此类对象本身。

使用纯虚拟的时间是当基础 class 根本没有可用的合理实现时。 想想像 stream 缓冲区这样的标准类型,基础只定义了一个接口,但对于许多操作,基础实际上没有任何事情要做。 只有派生类型知道它应该做什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM