Defining pure virtual method through multiple inheritance

Hello, I'd like to do something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

class A {
public:
    virtual void a() = 0;
};

class B {
public:
    void a() {}
    virtual void b() = 0;
};

class C : public A, public B {
public:
    C() {
        std::cout << "Hello World" << std::endl;
    }
    void b() {}
};

static C c;

int main() {

   return 0;
}


However, this code doesn't compile, even though C::a() should be defined. Why doesn't this work, and how can I fix it?
closed account (Dy7SLyTq)
can you have static global variables? even if you can it doesnt make any sense. it wont be deleted anyways because it doesnt go out of scope. as to your problem... using ideone i figured it out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

class A {
public:
    virtual void a() {};
};

class B {
public:
    void a() {}
    virtual void b() {};
};

class C : public A, public B {
public:
    C() {
        std::cout << "Hello World" << std::endl;
    }
    void b() {}
} c;

int main() {

   return 0;
}


you cant have virtual void identifier() = 0;
you need virtual void identifier() {}
@TC: I think the problem is closer to 'what a() do you have?' You inherit from two classes that define it. I'll try to look at this again later when I have more time to actually find the problem.

@DTSCode: Why can't you use = 0? That's the syntax for a pure virtual method.

In any case, static global scope was IIRC an old C way of created variables local to a compilation unit; in C++ I believe you usually use an anonymous namespace.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

struct A
{
    virtual ~A() {}
    virtual void foo() const = 0;
};

struct B
{
    virtual ~B() {}

    // B::foo does not *DOES NOT* override A::foo
    void foo() const { std::cout << "B::foo\n" ; }

    virtual void bar() const = 0 ;
};

struct C : A, B
{
    // override A::foo, forward to B::foo
    virtual void foo() const override { B::foo() ; }

    virtual void bar() const override { std::cout << "C::bar\n" ; }
};

int main()
{
    C c ;
    A& a = c ;
    a.foo() ; // B::foo
}

http://coliru.stacked-crooked.com/a/da6c40407a672fda
@ DTS: that has a slightly different meaning. He wants a() to be pure virtual in the a class... whereas that's not the case with your class.


@ OP:

The problem is because there are two different vtables here. One for the A class and one for the B class. Virtual functions from one do not "merge" with functions from the other unless they're part of the same inheritance tree. That is... C sees B::b as a non-virtual function whereas it sees A::b as a pure virtual function. It does not see B::b as an implementation of A::b.

To accomplish this, you'll need to ensure that both classes with implementations are part of the same tree (ie: they have a common parent).


Or if that's not an option, you can explicitly call B::a() from C::a() :

1
2
3
4
5
6
7
8
class C : public A, public B {
public:
    C() {
        std::cout << "Hello World" << std::endl;
    }
    void b() {}
    void a() { B::a(); }  // <-
};


Although this is rather "yukky"


EDIT: ninja'd

EDIT: also.. wtf why did DTS's post get reported?
Last edited on
closed account (Dy7SLyTq)
im going to stop posting here because this is now going over my head. im still too new to oop to understand what was told to me :} and yeah why was my post reported?
Topic archived. No new replies allowed.