c++中的多态——通过指针访问函数

Posted

技术标签:

【中文标题】c++中的多态——通过指针访问函数【英文标题】:Polymorphism in c++ - Access functions over pointers 【发布时间】:2020-10-17 17:48:12 【问题描述】:

得到以下简单结构:

    class Base 
    public:
        virtual void foo()  std::cout << "Base" << std::endl; 
    ;
    
    class Derived1 : public Base 
    public:
        void foo() override  std::cout << "Derived1" << std::endl; 
        void boo() 
    ;
    
    class Derived2 : public Base 
    public:
        void foo() override  std::cout << "Derived2" << std::endl; 
    ;
    
    int main()
        Base* p1 = new Derived1();
        Base* p2 = new Derived2();
    
        p1->foo();
        p1->boo();
    

现在我的问题是:如果我不希望 Derived2 的对象可以访问 Derived1::boo() 函数(使用指针 p1,所以我仍然具有多态性),如何访问它?

【问题讨论】:

你必须投射它。 一种方法是使用dynamic_cast&lt;Derived1*&gt;(base)static_cast&lt;Derived1*&gt;(base) 如果p1-&gt;boo() 应该对Derived2 对象无效,那么您的代码(假设比这个适当简化的示例更复杂)应该如何知道可以调用p1-&gt;boo()?指向Base 的指针,如p1,可以指向Derived2 对象。 【参考方案1】:

如果您可以确定指针指向Derived1 对象,那么static_cast 它:

static_cast<Derived1*>(p1)->boo();

如果您不知道它是否指向 Derived1 对象,那么您需要先使用 dynamic_cast 进行测试:

if (auto* as_derived1 = dynamic_cast<Derived1*>(p1)) 
    as_derived1->boo();

dynamic_cast 将评估为 nullptr 如果您正在转换的指针实际上并未指向 Derived1static_cast 不执行此检查,使​​其更快。但是,如果您要转换的指针实际上并不指向 Derived1 对象,那么访问结果指针会导致未定义的行为。

【讨论】:

【参考方案2】:

我不相信这段代码会编译?

p1 被作为Base* 访问,而Base* 没有声明或实现boo。如果您认为p1 实际上指向Derived1,则可以强制转换指针。

否则,您的类定义只会将boo 公开为Derived1 及其继承者的方法。

【讨论】:

这是常规的 C++ 指针转换,与您的问题无关。 static_castdynamic_cast 是两个选项。有大量资源提供更多信息。 好吧,做你想做的。 IMO 你的答案最好是独立和完整的。 c++ 支持 6 种不同类型的转换,我相信清晰度会很好,特别要使用哪些。另请注意:这不是我的问题 如果您希望在我的回答中看到改进,请随时提交修改! @ajm 当答案违背作者的意图时,编辑答案被认为是不合适的。您已表示您的意图是提供不完整的答案。因此,任何人都不应编辑您的答案以使其完整(除非您改变主意不要让答案不完整)。 @ajm 我明白了。您并不反对给出“常规 C++ 指针转换”的示例,而是您不知道如何(不进行额外研究)?

以上是关于c++中的多态——通过指针访问函数的主要内容,如果未能解决你的问题,请参考以下文章

[C++]——多态虚函数虚指针

[C++]——多态虚函数虚指针

[C++]——多态虚函数虚指针

C++中的虚函数以及虚函数表

c++八股之多态(持续更新)

C++多态:从虚表指针到设计模式