My attempt at a small hierarchy. Why doesn't my code compile?

P

PeteUK

See example code below. The instantiation of a Concrete object (see
main function) makes the compiler (VS 2003) complain that Concrete is
an abstract class because MethodsA::callA() and MethodsB::callB() are
not defined.

Hopefully it's obvious what I'm trying to acheive. Can someone tell me
where I'm going wrong?

Thanks,

Pete

// Low level interface
struct MethodsA
{
virtual ~MethodsA() {}
virtual void callA() = 0;
};

// Another low level interface
struct MethodsB
{
virtual ~MethodsB() {}
virtual void callB() = 0;
};

// Higher level interface - the main base class of concrete objects
struct MainBase
: public MethodsA,
public MethodsB
{
};

// A suggested implementation of a first low level interface
// Can be used as a mixin to easily create concrete objects
class ImplOfAMixin : public MethodsA
{
void callA() {}
};

// A suggested implementation of a second low level interface
// Can be used as a mixin to easily create concrete objects
class ImplOfBMixin : public MethodsB
{
void callB() {}
};

// Concrete class
class Concrete
: public MainBase, // "isa" main base
public ImplOfAMixin, // pull in this mixin
public ImplOfBMixin // and this mixin
{
};

int main()
{
Concrete obj;

return 0;
}
 
P

PeteUK

See example code below. The instantiation of a Concrete object (see
main function) makes the compiler (VS 2003) complain that Concrete is
an abstract class because MethodsA::callA() and MethodsB::callB() are
not defined.

Hopefully it's obvious what I'm trying to acheive. Can someone tell me
where I'm going wrong?

Thanks,

Pete

// Low level interface
struct MethodsA
{
    virtual ~MethodsA() {}
    virtual void callA() = 0;

};

// Another low level interface
struct MethodsB
{
    virtual ~MethodsB() {}
    virtual void callB() = 0;

};

// Higher level interface - the main base class of concrete objects
struct MainBase
    :    public MethodsA,
         public MethodsB
{

};

// A suggested implementation of a first low level interface
// Can be used as a mixin to easily create concrete objects
class ImplOfAMixin : public MethodsA
{
    void callA() {}

};

// A suggested implementation of a second low level interface
// Can be used as a mixin to easily create concrete objects
class ImplOfBMixin : public MethodsB
{
    void callB() {}

};

// Concrete class
class Concrete
    :    public MainBase,          // "isa" main base
         public ImplOfAMixin,      // pull in this mixin
         public ImplOfBMixin       // and this mixin
{

};

int main()
{
    Concrete obj;

    return 0;

}

In coming up with the example above I made an error but the problem
still remains. Here's the correction to make specify public on the
mixin classes:

// A suggested implementation of a first low level interface
// Can be used as a mixin to easily create concrete objects
class ImplOfAMixin : public MethodsA
{
public:
void callA() {}
};

// A suggested implementation of a second low level interface
// Can be used as a mixin to easily create concrete objects
class ImplOfBMixin : public MethodsB
{
public:
void callB() {}
};
 
A

Alf P. Steinbach

* PeteUK:
See example code below. The instantiation of a Concrete object (see
main function) makes the compiler (VS 2003) complain that Concrete is
an abstract class because MethodsA::callA() and MethodsB::callB() are
not defined.

Hopefully it's obvious what I'm trying to acheive. Can someone tell me
where I'm going wrong?

C++ isn't Java.

To emulate Java's interfaces, inherit every interface class virtually.

Since there's then only one base class sub-object of each interface, any
implementation of its member routines serves as implementation. :)


<code>
#ifdef _MSC_VER
#pragma warning( disable: 4250 ) // inherits via dominance
#endif

// Low level interface
struct MethodsA
{
virtual ~MethodsA() {}
virtual void callA() = 0;
};

// Another low level interface
struct MethodsB
{
virtual ~MethodsB() {}
virtual void callB() = 0;
};

// Higher level interface - the main base class of concrete objects
struct MainBase
: public virtual MethodsA
, public virtual MethodsB
{};

// A suggested implementation of a first low level interface
// Can be used as a mixin to easily create concrete objects
class ImplOfAMixin : public virtual MethodsA
{
public:
void callA() {}
};

// A suggested implementation of a second low level interface
// Can be used as a mixin to easily create concrete objects
class ImplOfBMixin : public virtual MethodsB
{
public:
void callB() {}
};

// Concrete class
class Concrete
: public MainBase, // "isa" main base
public ImplOfAMixin, // pull in this mixin
public ImplOfBMixin // and this mixin
{
};

int main()
{
Concrete obj;
}
</code>


Cheers & hth.,

- Alf
 
P

PeteUK

* PeteUK:

To emulate Java's interfaces, inherit every interface class virtually.

Since there's then only one base class sub-object of each interface, any
implementation of its member routines serves as implementation. :)

<snip>

Cheers & hth.,

- Alf

Alf - that does help. Thank you very much!

Pete
 
F

Fred Zwarts

PeteUK said:
See example code below. The instantiation of a Concrete object (see
main function) makes the compiler (VS 2003) complain that Concrete is
an abstract class because MethodsA::callA() and MethodsB::callB() are
not defined.

Hopefully it's obvious what I'm trying to acheive. Can someone tell me
where I'm going wrong?

Thanks,

Pete

// Low level interface
struct MethodsA
{
virtual ~MethodsA() {}
virtual void callA() = 0;
};

// Another low level interface
struct MethodsB
{
virtual ~MethodsB() {}
virtual void callB() = 0;
};

// Higher level interface - the main base class of concrete objects
struct MainBase
: public MethodsA,
public MethodsB
{
};

// A suggested implementation of a first low level interface
// Can be used as a mixin to easily create concrete objects
class ImplOfAMixin : public MethodsA
{
void callA() {}
};

// A suggested implementation of a second low level interface
// Can be used as a mixin to easily create concrete objects
class ImplOfBMixin : public MethodsB
{
void callB() {}
};

// Concrete class
class Concrete
: public MainBase, // "isa" main base
public ImplOfAMixin, // pull in this mixin
public ImplOfBMixin // and this mixin
{
};

int main()
{
Concrete obj;

return 0;
}

You have MethodsA and MethodsB twice in class Concrete.
MethodsA is once in MainBase and another time in ImplOfAMixin.
MethodsB is once in MainBase and another time in ImplOfBMixin.
The ones in MainBase are still pure virtual.

This can be solved with virtual inheritance, as mentioned in another reply.

Or, easier, you can skip class MainBase completely in class Concrete:

class Concrete
: public ImplOfAMixin, // pull in this mixin
public ImplOfBMixin // and this mixin

is sufficient.
 
P

PeteUK

Or, easier, you can skip class MainBase completely in class Concrete:

class Concrete
    :    public ImplOfAMixin,      // pull in this mixin
         public ImplOfBMixin       // and this mixin

is sufficient.

Fred,

What I didn't mention is that I hold a pointer elsewhere to something
that will need to talk to the concrete objects via both interfaces,
hence the introduction of MainBase.

Thanks,

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top