繁体   English   中英

C++ inheritance & 虚拟 function 问题

[英]C++ inheritance & virtual function problem

我想显示结果是 2。(现在结果是 1。)

我应该怎么做? (我想调用 B::test()。但实际上代码无法访问 main.c 中的 bh、b.c)

我也想知道从“public: virtual int test() {return 1;}”到“protected: virtual int test() {return 1;}”的错误啊

the inheritance relationship are super class A sub class B super class A sub class C

但我可以在 main.c 中访问 A class 我想要结果 2。(“a.test()”无法调用“b.test()”)

// a.h
#ifndef _A_
#define _A_

class A {
    public:
        A() {};
        ~A() {};
    //protected:
        virtual int test() {return 1;}
    private:
        friend class B;
};

#endif
// b.h
#ifndef _B_
#define _B_
#include "a.h"

class B : public A {
    public:
        B() {};
        ~B() {};
    private:
        int test() override;
        friend class A;
};

#endif
// b.c
#include "b.h"

int B::test()
{
    return 2;
}
// c.h
#ifndef _C_
#define _C_
#include "a.h"

class C : public A {
    public:
        C() {};
        ~C() {};
    private:
        int test() override;
        friend class A;
};

#endif
// c.c
#include "c.h"

int C::test()
{
    return 3;
}
// main.c
#include <iostream>
#include "a.h"

using namespace std;

int main(void)
{
    A *a = new A();
    cout << a->test() << "\n";
    return 0;
}

考虑您的代码:

// main.c
#include <iostream>
#include "a.h"

using namespace std;

int main(void)
{
    A *a = new A();
    cout << a->test() << "\n";
    return 0;
}

行为的关键决定因素是=new A()

如果你把它改成=new B()那么你会得到你想要的 '2' 的结果。

但是,您已经添加了限制“代码无法访问 b.h”。 这意味着=new B()不会编译。 这个限制从何而来? 您可以使用极其复杂的工厂模式来实现这一点,但这似乎不太可能是您想要做的。

访问说明符( privateprotectpublic )对于层次结构中的每个级别的相同方法(在本例中为test() )应该是相同的。 这不是由编译器绝对强制执行的,而是一个明确的最佳实践。 test() privateprotected之间几乎没有什么区别,但在这两种情况下,表达式:

a->test()  

将在 main 中失败,因为它在 class 之外,并且只能访问public成员。

还值得指出的是,您的friend声明在代码中完全没有必要,如图所示。

创建B类型的 object ,您仍然可以调用test方法,因为A::test是公共的。 此代码将打印 2:

int main(void)
{
    A *a = new B();
//             ^
    cout << a->test() << "\n";
    delete a;  // (1)
    return 0;
}

除非您将A的析构函数设为虚拟( 何时使用虚拟析构函数? ),否则第 (1) 行也无法正常工作:

class A {
    public:
        A() {};
        virtual ~A() {};
//      ^^^^^^^
    //protected:
        virtual int test() {return 1;}
    private:
        friend class B;
};

UPD如果由于某种原因您不能包含bh ,您可以执行以下操作:

ah

#ifndef _A_
#define _A_

class A {
    ...
};

A* CreateB();

#endif

a.c

#include "a.h"
#include "b.h"

...

A* CreateB() {
    return new B();
}

main.c

#include <iostream>
#include "a.h"

using namespace std;

int main(void)
{
    A *a = CreateB();
    cout << a->test() << "\n";
    delete a;
    return 0;
}

暂无
暂无

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

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