I'm setting a up an interface for various components of a framework in a personal project, and i've suddenly thought of something that i figured might be useful with an interface. My question is whether this is possible or not:
class a
{
public:
virtual class test = 0;
};
class b : public a
{
public:
class test
{
public:
int imember;
};
};
class c : public a
{
public:
class test
{
public:
char cmember; // just a different version of the class. within this class
};
};
sort of declaring a virtual class or pure virtual class, that is required to be defined within the derived object, so that you might be able to do something like this:
int main()
{
a * meh = new b();
a * teh = new c();
/* these would be two different objects, but have the same name, and still be able
to be referred to by an interface pointer in the same way.*/
meh::test object1;
teh::test object2;
delete meh;
delete teh;
return 0;
}
msvc++ throws me a bunch of syntax errors, so is there a way to do this, and i'm just not writing it right?
No, it isn't valid. In any case, C++ has no concept of virtual classes as such. You can probably achieve what you want by holding a pointer to a certain class with only pure virtual methods (although that isn't a requirement):
class ITest { /* full of pure virtual methods... maybe. */};
class a
{
public:
virtual ITest* someFunctionName()=0 ;
private:
ITest* test_;
};
Then you can decide to inherit from a, giving each implementation concrete implementations of ITest, or some other approach, such as deciding which implementation to use based on some constructor parameter, for example.
The keyword "virtual" merely means "table to dispatch function call.
What you proposed is not part of the language.
But you can approach it in another way, by chaining the object creation to proper virtual calls:
#include <iostream>
using namespace std;
class a
{
public:
class test
{
public:
virtual ~test() {} ///< required to have polimorphic behavior
virtual void hello() const =0;
};
virtual test* create_test()=0;
};
class b: public a
{
public:
class test_b: public a::test
{
virtual void hello() const
{ cout << "this is test_b at " << this << endl; }
};
virtual test* create_test()
{ return new test_b; }
};
class c: public a
{
public:
class test_c: public a::test
{
virtual void hello() const
{ cout << "this is test_c at " << this << endl; }
};
virtual test* create_test()
{ return new test_c; }
};
int main()
{
a* pa1 = new b;
a* pa2 = new c;
a::test* p1 = pa1->create_test();
a::test* p2 = pa2->create_test();
p1->hello();
p2->hello();
delete p2; delete p1;
delete pa2; delete pa1;
}
Related
#include <iostream>
class A {
protected:
int foo;
};
class B : public A {
public:
B(int bar) { foo = bar; }
int method() { return foo; }
};
class C {
private:
A baz;
public:
C(A faz) { baz = faz; }
A get() { return baz; }
};
int main(void) {
C boo(B(1));
std::cout << boo.get().method() << std::endl;
return 0;
}
I have a base class A which B is a derived class of. Class C takes an A yet I have passed a derived class (B) in its place. No warnings or errors passing a B to C, but I'd like to have method visibility of method() in the above situation.
I'm not very familiar with virtual but I did try to add virtual int method() = 0; to A which lead to further errors.
Consider were I to add a second derived class:
class D : public A {
public:
D(int bar) { foo = bar; }
int method() { return foo+1; }
};
I'd like C to be able to take either B or D and my best assumption would be to take an A and let it handle it.
How do I use polymorphism correctly in this fashion?
Expected output with the below:
int main(void) {
C boo(B(1));
C boz(D(2));
std::cout << boo.get().method() << std::endl;
std::cout << boz.get().method() << std::endl;
return 0;
}
Would be:
1
3
First of all, in order to use A polymorphically, you need to add a virtual destructor, otherwise you will run into undefined behavior when trying to destroy the object. Then the method that you want to call through A must be virtual as well. If it shouldn't have an implementation in the base class itself, make it pure virtual:
class A {
protected:
int foo;
public:
virtual ~A() {}
virtual int method() = 0;
};
Then in C you need to use pointers or references to A, since polymorphism only works with those.
If you want C to own the A, as your code example to suggest, then you need to provide a destructor deleting the pointer and you need to disable copying of the class (or decide on some useful semantics for it):
class C {
private:
C(const C&); // Don't allow copying
C& operator=(const C&); // Don't allow copying
A* baz;
public:
C(A* faz) : baz(faz) { }
~C() { delete baz; }
A& get() { return *baz; }
};
int main(void) {
C boo(new B(1));
C boz(new D(2));
std::cout << boo.get().method() << std::endl;
std::cout << boz.get().method() << std::endl;
return 0;
}
Ideally you would upgrade to C++11 and use std::unique_ptr<A> instead of A* as member. But even if you can't do that, consider using boost::scoped_ptr<A>, which will manage the deletion for you (you don't need the destructor) and will make the class non-copyable by default. It also provides better exception-safety to encapsulate allocations in smart pointers like that.
If you need to call method() of type B using base class type A there has to be lookup during the runtime. The lookup is necessary to answer the question: Which method should be called? - the one that corresponds the type in a current line? Or other method in inheritance hierarchy?" If you expect method() from class B to be called when you have pointer or reference to A then you have to create a lookup table. This table is called vtable (from virtual functions table) and it's defined by adding virtual keyword to functions.
#include <iostream>
class A {
public:
virtual ~A(){}
virtual int method() = 0;
protected:
int foo;
};
class B : public A {
public:
B(int bar) { foo = bar; }
int method() {
std::cout << "Calling method() from B" << std::endl;
return foo; }
};
class C {
private:
A* baz;
public:
C(A* faz) { baz = faz; }
A* get() { return baz; }
};
int main(void) {
A* element = new B(1);
C boo(element);
boo.get()->method();
return 0;
}
It prints "Calling method() from B". Please keep in mind that the code is for presentation purposes and it's not good from best practices perspective.
I have a base class instance, there is a derived class that inherits from the base class, I want to transform the base instance into derived instance, (if possible without copying anything (maybe sending to the derived class a reference of the base class)) how can I achieve that?
Note: I need this because I'm using factory design pattern which identify the derived class needed to be created using a parameter located in the base instance.
//class A
//class B: public A (pure virtual)
//class C: public B
B BFactory::makeB(A &a) {
int n=a.getN();
if(n==1){
return new C();
}
}
Thanks.
Consider the case of the car.
You can treat a Lamborghini as a car.
You can treat a Yugo as a car.
You can treat a car as a Lamborghini if it is a Lamborghini. In C++ this means a pointer to car that really points to a Lamborghini. In order to get a Lamborghini pointer back out of the car pointer you should use dynamic_cast. If the car does not point to a Lamborghini, dynamic_cast will return NULL. This keeps you from trying to pass off a Yugo as a Lamborghini and blowing the Yugo's engine.
But when the Lamborghini is being treated as a car, it can only do car things. If you copy a Lamborghini into a car, you strip out all Lamborghini-ness forever. It's gone.
Code time!
This, I'm afraid cannot be done:
//class A
//class B: public A (pure virtual)
//class C: public B
B BFactory::makeB(A &a) {
int n=a.getN();
if(n==1){
return new C();
}
}
C is being copied into a B and the B is being returned. B would need a constructor that took a C, but the point is moot. B cannot be instantiated if it's pure virtual. For now we'll ignore the leak that would be new C()
Also can't use a reference for this job, pretty much the same problem, so you're trapped into returning a pointer
B * BFactory::makeB(A &a) {
int n=a.getN();
if(n==1){
return new C();
}
}
Now I'm going to make a suggestion: Build the make function into B and handle the case where A doesn't map to anything recognized by B.
class B: public A
{
public:
virtual ~B(){}
static B * makeB(A & a)
{
switch(a.getN())
{
case 1:
return new C();
}
return NULL;
}
};
But this leads to another recommendation: Why should B know anything? And What is the point of A at this level? Why is A storing build codes for classes two or more steps down the hierarchy? Bad from a maintenance point of view. The point of objects is they know who they are and how to manipulate themselves. Short-circuiting this leads to pain.
class B: public A
{
public:
virtual ~B(){}
virtual B* makeB() = 0;
};
Now B only makes Bs, needs no help from A, and those who extend B are stuck with figuring out how to make themselves--a task they should know better than anyone else. Much safer because there is never any possibility of a code unrecognised by B for a new class.
class C: public B
{
public:
B* makeB()
{
return new C();
}
};
class D: public B
{
public:
B* makeB()
{
return new D();
}
};
Edit: Traditional factory
You're asking for an abstract factory. For that you need nothing. You don't even need a class. You certainly don't need a class A. The goal of this sort of factory is the caller knows nothing about the class. By providing an A, the caller needs to know how to make an A or have another factory that makes an A.
First a bit of set-up in a header file BFactory.h:
#ifndef BFACTORY_H_
#define BFACTORY_H_
#include <exception>
class B
{
public:
virtual ~B(){}
virtual std::string whatAmI() = 0;
protected:
// data members common to all B subclasses
};
enum bType
{
gimmie_a_C,
gimmie_a_D,
gimmie_an_E
};
class BadTypeException: public std::exception
{
public:
const char* what() const noexcept
{
return "Dude! WTF?!?";
}
};
B* BFactory(enum bType type);
#endif /* BFACTORY_H_ */
Here I'm going to deviate from the book way a little. Rather than using an integer to identify the type to be built, I'm going to use an enum. Two reasons: Easier to read and understand gimme_a_C than 1 and generates a compiler error if you try to provide a value that is not enumerated.
enum bType
{
gimmie_a_C,
gimmie_a_D,
gimmie_an_E
};
And an exception to flag stupidity if the enum is updated with new types (gimmie_an_E) but the factory is not.
class BadTypeException: public std::exception
{
public:
const char* what() const noexcept
{
return "Dude! WTF?!?";
}
};
This is all the Factory client needs to see. They don't see C. They don't see D. They have no clue that C and D exist in any way other than the names listed in enum bType. All they ever see is pointers to B.
Now for the implementation BFactory.cpp:
#include "BFactory.h"
class C:public B
{
std::string whatAmI()
{
return "C";
}
};
class D:public B
{
std::string whatAmI()
{
return "D";
}
};
B* BFactory(enum bType type)
{
switch(type)
{
case gimmie_a_C:
return new C();
case gimmie_a_D:
return new C();
default:
throw BadTypeException();
}
}
I'll leave it up to the reader to spot the stupid bug in the above code that makes these error prone and why I don't like them.
And usage, main.cpp:
#include "BFactory.h"
int main()
{
B * temp;
temp = BFactory(gimmie_a_C);
std::cout << temp->whatAmI() << std::endl;
delete temp;
temp = BFactory(gimmie_a_D);
std::cout << temp->whatAmI() << std::endl;
delete temp;
//temp = BFactory(1001); // won't compile
try
{
temp = BFactory(gimmie_an_E); // will compile, throws exception
std::cout << temp->whatAmI() << std::endl;
}
catch(BadTypeException& wtf)
{
std::cerr << wtf.what() << std::endl;
}
}
There is still absolutely no use for or involvement of A. A if it exists, should no nothing about B or the children of B.
These days there is a little improvement we can make so that the pointers are a little safer. unique_ptr allows us to maintain the polymporphic advantages of a pointer to B without the memory management woes.
std::unique_ptr<B> BFactory(enum bType type)
{
switch(type)
{
case gimmie_a_C:
return std::unique_ptr<B>(new C());
case gimmie_a_D:
return std::unique_ptr<B>(new D());
default:
throw BadTypeException();
}
}
and the new main:
int main()
{
std::unique_ptr<B> temp;
temp = BFactory(gimmie_a_C);
std::cout << temp->whatAmI() << std::endl;
temp = BFactory(gimmie_a_D);
std::cout << temp->whatAmI() << std::endl;
}
You might want to define a constructor that takes the base class instance as the argument so you can later use static_cast to convert from the base class to the derived class.
class Derived : public Base
{
public:
Derived(const Base& base) : Base{base} {}
};
int main()
{
Base a;
Derived b = static_cast<Derived>(a);
}
If you want to create a derived class instance using the base class instance then there is some conversion rule between the two, which you can specify explicitly using a derived class constructor.
Although it is impossible to alter the type of an object you still can make instances of base and derived classes share the same data:
#include <memory>
#include <iostream>
class Base
{
protected:
struct CommonData
{
int A;
int B;
};
std::shared_ptr<CommonData> m_data;
public:
Base() : m_data(std::make_shared<CommonData>())
{
m_data->A = 0;
m_data->B = 0;
}
void SetData(Base * source)
{
m_data = source->m_data;
}
int A() const { return m_data->A; }
int B() const { return m_data->B; }
void SetA(int value) { m_data->A = value; }
void SetB(int value) { m_data->B = value; }
};
class Derived : public Base
{
public:
int C;
};
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
Base base;
base.SetA(12);
base.SetB(46);
Derived derived;
derived.SetData(&base);
derived.C = 555;
cout << derived.A() << endl; // 12
cout << derived.C << endl; // 555;
cin.get();
}
A base class should not "know" about how to make its own derived class instances. That is the point of inheritance.
The "is a" relationship of derived classes means that any subclass instance will pass as a base class instance transparently, and you can treat it as one, and by default base class non-virtual methods are called on a base class reference, even if it a derived class instance. Only virtual methods use the derived class method.
In the case of creating a base class instance from a derived class you want to "slice" the instance data (normally a bad thing and normally a mistake).
class A{ // ... A stuff };
class B : A
{ // ... B stuff
A make_A() { return (A) B(*this); } // copy cast to A
};
Under no circumstances try to do this:
class B;
class A { // ...
B make_B() { return B(*this); }
};
That is inverted OO logic. It requires at least 2 scans of the source code, which C++ does not do. It fails.
If I have two abstract classes defining a pure virtual function with the same name, but different, non-covariant return types, how can I derive from these and define an implementation for both their functions?
#include <iostream>
class ITestA {
public:
virtual ~ITestA() {};
virtual float test() =0;
};
class ITestB {
public:
virtual ~ITestB() {};
virtual bool test() =0;
};
class C : public ITestA, public ITestB {
public:
/* Somehow implement ITestA::test and ITestB::test */
};
int main() {
ITestA *a = new C();
std::cout << a->test() << std::endl; // should print a float, like "3.14"
ITestB *b = dynamic_cast<ITestB *>(a);
if (b) {
std::cout << b->test() << std::endl; // should print "1" or "0"
}
delete(a);
return 0;
}
As long as I don't call C::test() directly there's nothing ambiguous, so I think that it should work somehow and I guess I just didn't find the right notation yet. Or is this impossible, if so: Why?
Okay, it is possible, and the way isn't too ugly. I have to add an additional level of inheritance:
ITestA ITestB <-- These are the interfaces C has to fulfill, both with test()
| |
ITestA_X ITestB_X <-- These classes implement the interface by calling a
| | function with a different name, like ITestA_test
\__________/ which is in turn pure virtual again.
|
C <-- C implements the new interfaces
Now C has no function test(), but when casting a C* to an ITestA*, the implementation of test() in ITestA_test will be used. When casting it to an ITestB*, even by a dynamic_cast from the ITestA*, the implementation of ITestB_test will be used.
The following program prints:
3.14
0
#include <iostream>
class ITestA {
public:
virtual ~ITestA() {};
virtual float test() =0;
};
class ITestB {
public:
virtual ~ITestB() {};
virtual bool test() =0;
};
class ITestA_X : public ITestA {
protected:
virtual float ITestA_test() =0;
virtual float test() {
return ITestA_test();
}
};
class ITestB_X : public ITestB {
protected:
virtual bool ITestB_test() =0;
virtual bool test() {
return ITestB_test();
}
};
class C : public ITestA_X, public ITestB_X {
private:
virtual float ITestA_test() {
return 3.14;
}
virtual bool ITestB_test() {
return false;
}
};
int main() {
ITestA *a = new C();
std::cout << a->test() << std::endl;
ITestB *b = dynamic_cast<ITestB *>(a);
if (b) {
std::cout << b->test() << std::endl;
}
delete(a);
return 0;
}
Does this have any drawbacks you could think of?
When you declare ITestA *a = new C(), you have created a C object. If you invoke test on it with a->test(), it has to use the C virtual table to find the code to execute. But C is trying to have two different implementations of the same signature test(), which isn't allowed. The fact that you declared it as an ITestA * doesn't affect the method resolution. You declared the methods virtual, so they are found via the actual type of the object, regardless of the type of the pointer you used to access it.
You cannot have two methods with the same name and argument types. You'll need to find another way to structure this code.
I don't think this is possible. Functions overload by name (and signature).
Coluld you provide a simple code example? (sorry C++ nube) and how to call a function from the class you are extending?
A bit useful example: :-)
class CImplementation
{
public:
void doFoo();
};
void CImplementation::doFoo()
{
//implementation
}
class IInterface
{
public:
virtual void foo()=0;
};
class DerivedFromImplementationAndInterface : public CImplementation, public IInterface
{
virtual void foo();
};
void DerivedFromImplementationAndInterface::foo()
{
doFoo();
}
//possible usage:
void method(IInterface& aInterface)
{
aInterface.foo();
}
void test()
{
IInterface* d = new DerivedFromImplementationAndInterface;
method(*d);
}
In C++, you can extend multiple classes, it's called multiple inheritance. Most probably this is what you're looking for. Please read a good book about multiple inheritance and C++ (a quick introduction: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr134.htm), because there are many pitfalls and details to pay attention to.
Example for multiple inheritance:
class A { ... };
class B { ... };
class C: public A, public B {}; // C inherits from A and B.
C++ doesn't explicitly have interfaces, the equivalent of an interface in Java is usually implemented with a class having only pure virtual functions (plus constructors, destructor, copy assignment):
#include <iostream>
// interface
class Fooable {
public:
virtual int foo() = 0;
virtual ~Fooable() {}
};
// base class
class Base {
public:
void non_virtual_function() { std::cout << "Base::non_virtual_function\n"; }
virtual void virtual_function() { std::cout << "Base::virtual_function\n"; }
};
// derived class, inherits from both Base "class" and Fooable "interface"
class Derived: public Base, public Fooable {
public:
virtual int foo() {
// call base class function
Base::non_virtual_function();
// virtual call to function defined in base class, overridden here
virtual_function();
}
virtual void virtual_function() {
// call base class implementation of virtual function directly (rare)
Base::virtual_function();
std::cout << "Derived::virtual_function\n";
}
void non_virtual_function() {
// not called
std::cout << "Derived::non_virtual_function\n";
}
};
int main() {
Derived d;
d.foo();
}
Not sure what you're asking:
class A
{
public:
void method();
};
class B
{
public:
void method();
};
class C : public A, public B
{
public:
void callingMethod();
};
void C::callingMethod()
{
// Here you can just call A::method() or B::method() directly.
A::method();
B::method();
}
Note that multiple inheritance can lead to really hard-to-solve problems and I would recommend to only use it when necessary.
The question as stated,
C++ is it possible to make a class extend one class and implement another?
does not make much sense. The answer to that is just "yes". You can derive from any number of classes: C++ fully support multiple inheritance.
So, given that the question as stated isn't really meaningful, it's at least possible that you meant to ask
C++ is it possible to make a class extend one class and thereby implement another?
The answer to this question is also yes, but it's not trivial. It involves virtual inheritance. Which is quite tricky.
Here's an example:
#include <iostream>
void say( char const s[] ) { std::cout << s << std::endl; }
class TalkerInterface
{
public:
virtual void saySomething() const = 0;
};
class TalkerImpl
: public virtual TalkerInterface
{
public:
void saySomething() const
{
say( "TalkerImpl!" );
}
};
class MyAbstractClass
: public virtual TalkerInterface
{
public:
void foo() const { saySomething(); }
};
class MyClass
: public MyAbstractClass
, public TalkerImpl
{};
int main()
{
MyClass().foo();
}
The virtual inheritance ensures that there is only one sub-object of type TalkerInterface in a MyClass instance. This has some counter-intuitive consequences. One is that "inheriting in an implementation" works, and another is that construction of that base class sub-object happens down in each MyClass constructor, and more generally down in the most derived class.
Cheers & hth.,
In my class design I ran into the following problem:
class MyData
{
int foo;
};
class AbstraktA
{
public:
virtual void A() = 0;
};
class AbstraktB : public AbstraktA
{
public:
virtual void B() = 0;
};
template<class T>
class ImplA : public AbstraktA
{
public:
void A(){ cout << "ImplA A()"; }
};
class ImplB : public ImplA<MyData>, public AbstraktB
{
public:
void B(){ cout << "ImplB B()"; }
};
void TestAbstrakt()
{
AbstraktB *b = (AbstraktB *) new ImplB;
b->A();
b->B();
};
The problem with the code above is that the compiler will complain that AbstraktA::A() is not defined.
Interface A is shared by multiple objects. But the implementation of A is dependent on the template argument. Interface B is the seen by the outside world, and needs to be abstrakt.
The reason I would like this is that it would allow me to define object C like this:
Define the interface C inheriting from abstrakt A.
Define the implementation of C using a different datatype for template A.
I hope I'm clear. Is there any way to do this, or do I need to rethink my design?
You have two paths of inheritance from AbstracktA, you implement AbstraktA::A() only in one of them, so the compiler complains.
You probably want to inherit virtually from AbstraktA in both case so that there is only one AbstraktA base object (add virtual before AbstraktA).
I forgot to add virtual destructors to the base classes. This leads to runtime malloc errors I believe.
AbstraktB *b = new ImplB;
b->A();
b->B();
delete b;
In debug mode, at the delete statement, GCC gives me:
malloc: *** error for object 0x60e2c4: pointer being freed was not allocated
I solved this by changing the base classes to:
class AbstraktA
{
public:
virtual ~AbstraktA(){};
virtual void A() = 0;
};
class AbstraktB : virtual public AbstraktA
{
public:
virtual ~AbstraktB(){};
virtual void B() = 0;
};