1

I want to show result is 2. (Now result is 1.)

How should I do? (I want to call B::test(). But Actually code cannot access b.h, b.c in main.c)

also I want to know that error from "public: virtual int test() {return 1;}" to "protected: virtual int test() {return 1;}" in a.h

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()")

// 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;
}

3
  • 2
    I'd suggest changing your title and tags. this is NOT multiple inheritance. Multiple inheritance is where on class has two immediate parents: class C : public A, public B ... Commented Apr 5, 2020 at 8:39
  • 1
    code cannot access b.h, b.c in main.c Why is that? Commented Apr 5, 2020 at 8:55
  • I posted only a summary of the actual code problem. Commented Apr 5, 2020 at 9:38

2 Answers 2

1

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().

If you change this to =new B() then you would get the result of '2' that you want.

However, you've had added the restriction 'code cannot access b.h'. This means that =new B() will not compile. 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. 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:

a->test()  

will fail in main, because it is outside of the class, and can only access public members.

Also worth pointing out that your friend declarations are entirely unnecessary in the code as shown.

Sign up to request clarification or add additional context in comments.

1 Comment

his means that =new B() will not compile. 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. I will do it. thanks your advice.
0

Create object of type B, you still will be able to call test method, because A::test is public. This code will print 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?):

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 b.h you can do the following:

a.h:

#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;
}

3 Comments

the main.c cannot access class B and class C(b.h, b.c, c.h, c.c).
@AndrewChang added example how you may deal with it
thanks to your advice. But doesn't work... /tmp/ccrGMeiu.o: In function A::A()': main.c:(.text._ZN1AC2Ev[_ZN1AC5Ev]+0xb): undefined reference to vtable for A' collect2: error: ld returned 1 exit status

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.