简体   繁体   English

C++ inheritance & 虚拟 function 问题

[英]C++ inheritance & virtual function problem

I want to show result is 2. (Now result is 1.)我想显示结果是 2。(现在结果是 1。)

How should I do?我应该怎么做? (I want to call B::test(). But Actually code cannot access bh, b.c in main.c) (我想调用 B::test()。但实际上代码无法访问 main.c 中的 bh、b.c)

also I want to know that error from "public: virtual int test() {return 1;}" to "protected: virtual int test() {return 1;}" in ah我也想知道从“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 the inheritance relationship are super class A sub class B super class A sub class C

but I can access A class in main.c I want to result 2. ("a.test()" could not call "b.test()")但我可以在 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;
}

Consider your code:考虑您的代码:

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

using namespace std;

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

The key decider on behaviour is =new A() .行为的关键决定因素是=new A()

If you change this to =new B() then you would get the result of '2' that you want.如果你把它改成=new B()那么你会得到你想要的 '2' 的结果。

However, you've had added the restriction 'code cannot access b.h'.但是,您已经添加了限制“代码无法访问 b.h”。 This means that =new B() will not compile.这意味着=new B()不会编译。 Where does this restriction come from?这个限制从何而来? You could achieve this with an extremely complicated factory pattern, but it seems unlikely this is what you are trying to do.您可以使用极其复杂的工厂模式来实现这一点,但这似乎不太可能是您想要做的。

Access specifiers ( private , protect , public ) should be the same for the same method ( test() in this case) at every level in the hierarchy.访问说明符( privateprotectpublic )对于层次结构中的每个级别的相同方法(在本例中为test() )应该是相同的。 This is not absolutely enforced by the compiler, but is a clear best practice.这不是由编译器绝对强制执行的,而是一个明确的最佳实践。 There's very little difference her between making test() private or protected , but in both cases the expression:test() privateprotected之间几乎没有什么区别,但在这两种情况下,表达式:

a->test()  

will fail in main, because it is outside of the class, and can only access public members.将在 main 中失败,因为它在 class 之外,并且只能访问public成员。

Also worth pointing out that your friend declarations are entirely unnecessary in the code as shown.还值得指出的是,您的friend声明在代码中完全没有必要,如图所示。

Create object of type B , you still will be able to call test method, because A::test is public.创建B类型的 object ,您仍然可以调用test方法,因为A::test是公共的。 This code will print 2:此代码将打印 2:

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

Also line (1) won't work properly unless you make A 's destructor virtual ( When to use virtual destructors? ):除非您将A的析构函数设为虚拟( 何时使用虚拟析构函数? ),否则第 (1) 行也无法正常工作:

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

UPD If for some reason you can't include bh you can do the following: UPD如果由于某种原因您不能包含bh ,您可以执行以下操作:

ah : ah

#ifndef _A_
#define _A_

class A {
    ...
};

A* CreateB();

#endif

a.c : a.c

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

...

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

main.c : 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