首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++继承和虚函数问题

C++继承和虚函数问题
EN

Stack Overflow用户
提问于 2020-04-05 16:37:10
回答 2查看 62关注 0票数 1

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

我该怎么办?(我想调用B::test()。但实际上代码不能访问main.c中的b.h,b.c )

我还想知道在a.h中从"public: virtual int test() {return 1;}“到"protected: virtual int test() {return 1;}”的错误

继承关系为超类A子类B超类A子类C

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

代码语言:javascript
复制
// a.h
#ifndef _A_
#define _A_

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

#endif
代码语言:javascript
复制
// b.h
#ifndef _B_
#define _B_
#include "a.h"

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

#endif
代码语言:javascript
复制
// b.c
#include "b.h"

int B::test()
{
    return 2;
}
代码语言:javascript
复制
// c.h
#ifndef _C_
#define _C_
#include "a.h"

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

#endif
代码语言:javascript
复制
// c.c
#include "c.h"

int C::test()
{
    return 3;
}
代码语言:javascript
复制
// main.c
#include <iostream>
#include "a.h"

using namespace std;

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

回答 2

Stack Overflow用户

发布于 2020-04-05 16:49:38

考虑你的代码:

代码语言:javascript
复制
// 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‘。

这意味着=new B()将不会编译。这种限制是从哪里来的?您可以通过一个极其复杂的工厂模式来实现这一点,但这似乎不是您想要做的事情。

层次结构中每个级别的同一方法(本例中为test())的访问说明符(privateprotectpublic)应该相同。her在制作test() privateprotected之间几乎没有区别,但在这两种情况下,表达式都是:

代码语言:javascript
复制
a->test()  

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

同样值得指出的是,您的friend声明在代码中是完全不必要的,如下所示。

票数 1
EN

Stack Overflow用户

发布于 2020-04-05 16:51:36

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

代码语言:javascript
复制
int main(void)
{
    A *a = new B();
//             ^
    cout << a->test() << "\n";
    delete a;  // (1)
    return 0;
}

此外,除非您将A的析构函数设为虚的(When to use virtual destructors?),否则第(1)行将无法正常工作:

代码语言:javascript
复制
class A {
    public:
        A() {};
        virtual ~A() {};
//      ^^^^^^^
    //protected:
        virtual int test() {return 1;}
    private:
        friend class B;
};

更新如果由于某种原因不能包含b.h,您可以执行以下操作:

a.h

代码语言:javascript
复制
#ifndef _A_
#define _A_

class A {
    ...
};

A* CreateB();

#endif

a.c

代码语言:javascript
复制
#include "a.h"
#include "b.h"

...

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

main.c

代码语言:javascript
复制
#include <iostream>
#include "a.h"

using namespace std;

int main(void)
{
    A *a = CreateB();
    cout << a->test() << "\n";
    delete a;
    return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61040004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档