Must virtual methods be always implemented in derived class?
Can I write something like this?
<!-- language: lang-cpp -->
class BaseInterface
{
public:
virtual void fun_a() = 0;
virtual void fun_b() = 0;
virtual ~BaseInterface();
};
class Derived : public BaseInterface
{
void fun_a() { ... };
};
class FinalClass : public Derived
{
void fun_b() { ... };
}
int main()
{
FinalClass test_obj;
test_obj.fun_a(); // use Derived implementation or fail ???
test_obj.fun_b(); // use own implementation
BaseInterface* test_interface = new FinalClass();
test_interface->fun_a(); // fail or ok ???
test_interface->fun_b();
}
Is the code above correct?
Does another virtual method outflank exist?
Pure virtual methods always must be reimplemented in derived class?
Actually a derived class which is going to be instantiated.
In your code, you didn't make an object from Derived so it's OK.
Can i write something like this?
Yes.
You had some minor errors that I corrected them:
class BaseInterface
{
public:
virtual void fun_a() = 0;
virtual void fun_b() = 0;
virtual ~BaseInterface() {}; // You forget this
};
class Derived : public BaseInterface
{
public:
void fun_a() {} // This should be public as its base
};
class FinalClass : public Derived
{
public:
void fun_b() {} // This should be public as its base
};
int main()
{
FinalClass test_obj;
test_obj.fun_a();
test_obj.fun_b();
BaseInterface* test_interface = new FinalClass();
test_interface->fun_a();
test_interface->fun_b();
}
It makes Derived also an abstract class which you cannot instantiate, seeing you don't implement all the virtual functions from it's base, it becomes an abstract class you cannot directly instantiate.
See here: liveworkspace.org/code/6huYU$10
For the rest, your code should work.
Code is correct.
There is no special concept for interface in C++. All are classes. Some of the class methods can be pure virtual. It only means that compiler cannot create an instance of such class.
Related
I am trying to figure out how to arrange some classes. This is what I've got so far ...
The top of the inheritance hierarchy is (naturally) T:
(T.h)
namespace foo
{
class T
{
public:
virtual void method1(std::string a_parameter) = 0;
virtual void method2() = 0;
};
}
I have two sub-classes of T with some additional methods - here are
the header files:
(A.h)
namespace foo
{
class A : public T
{
public:
virtual ~A() {};
virtual void method3() = 0;
//and a factory function
static A* gimmeAnAyy();
};
}
(B.h)
namespace foo
{
class B : public T
{
public:
virtual ~B() {};
virtual void method4() = 0;
//and a factory function
static B* gimmeABee();
};
}
The implementation classes are in the respective .cpp files:
(A.cpp)
namespace foo
{
class AImpl : public A
{
public:
A(std::string member_data) : m_member_data(member_data) {};
~A() {};
void method3()
{
//something really important, can't think of it right now ;-)
};
private:
std::string m_member_data;
};
A* A::gimmeAnAyy()
{
return new AImpl("this is an impl of A");
};
}
(B.cpp)
namespace foo
{
class BImpl : public B
{
public:
B(std::string other_data) : m_other_data(other_data) {};
~B() {};
void method4()
{
//something really important, can't think of it right now ;-)
};
private:
std::string m_other_data;
};
B* B::gimmeABee()
{
return new BImpl("this is an imll of B");
};
}
Now the compiler complains - rightly so - about the virtual functions
method1() and method2() that I haven't implemented in AImpl and BImpl.
What I want is a TImpl class that both AImpl and BImpl can inherit from
so that I don't have to implement method1() and method2() in two different .cpp files.
Is it possible? Am I out to lunch? Am I asking too many rhetorical questions for a StackExchange post?
Thanks in advance,
Mike
Yeah, it is possible. Common practice is to use the following snippet:
template<typename Interface>
class TImpl : public Interface
{
public:
virtual void method1(std::string a_parameter) { /* implementation */ }
virtual void method2() { /* implementation */ }
};
And then inherit from it as follows:
class Aimpl : public TImpl<A>
{
public:
virtual void method3() { /* implementation */ }
};
class Bimpl : public Timpl<B>
{
public:
virtual void method4() { /* implementation */ }
};
You can put implementation of Timpl in cpp file, but then you have to explicitly instantiate it for every possible interface. This is done as follows in the cpp:
template<typename Interface>
void Timpl<Interface>::method1(std::string a_parameter)
{
/* implementation */
}
template<typename Interface>
void Timpl<Interface>::method2()
{
/* implementation */
}
template class Timpl<A>;
template class Timpl<B>;
Do not make method1 and method2 pure virtual functions. Give them an implementation!
i.e.
declare
class T
{
public:
virtual void method1(std::string a_parameter);
virtual void method2();
};
Define:
void T::method1(std::string a_parameter) { // Could use const/reference here perhaps
....
}
etc...
It seems your problem is the wrong believe that it is better to have only pure virtual functions in your base class! Just get over it and provide a default implementation in T. Although there are religious believes that is bad, there isn't any technical reason not to have it. Insisting in having only pure virtual functions in base classes is like insisting in all music having to be 12-tone music!
since both of the son classes (A & B) don't have (method1, method2) then you don't have to use the virtual. you can easily provide a default implementation in the base class and then invoke and use these methods through the inheritance chain since the inheritance type here is public.
In the A and B classes declaration, the methods 3 and 4 are pure virtual, so in the definition file you shouldn't gives an implementation of them. In my understand A and B are leading the implementation of the T methods and their own virtual methods to other concrete classes who inherit from them. If you thing that A and B are concrete classes, put away the "= 0" from the following lines:
class A : public T
{
public:
virtual ~A() {};
virtual void method3() = 0; // <-- Here
//and a factory function
static A* gimmeAnAyy();
};
class B : public T
{
public:
virtual ~B() {};
virtual void method4() = 0; // <-- and Here
//and a factory function
static B* gimmeABee();
};
If doesn't want to implement the methods 1 and 2 of the T class, give an empty or a default implementation to them, in the T class or in the A and B classes.
But consider this, if you inherits from an interface, is expected that you IMPLEMENT that interface. :)
Lets suppose you want to make an interface of the class Derived and it looks like this:
class Derived : public Base
{
public:
foo();
}
class Base
{
public:
tii();
//many other methods
}
How would you do the Interface? How can you make Base::tii visible (and also other methods) to this new interface?
class IDerived
{
public:
virtual foo() = 0;
// should I declare here tii() as a pure virtual function?
// but by doing it now there is ambiguity!
}
What is a good strategy?
The new Derived class should look like this....
class Derived : public Base, public IDerived
{
//implement the real thing
}
Your example is doing things backwards: the interface should be defined independently of any concrete classes with all pure virtual methods:
class IDerived
{
public:
virtual void foo() = 0;
virtual ~IDerived() {} // don't forget to include a virtual destructor
}
And the concrete classes will derive publicly from the interface:
class Derived : public Base, public IDerived
{
public:
void foo();
}
If you want IDerived to also declare methods that Derived inherits from Base, you can have Derived explicitly implement the method by calling the inherited implementation:
class Derived : public Base, public IDerived
{
public:
void foo();
void bar() { Base::bar(); }
}
At front, I dislike interfaces (they are grown by other languages than c++).
Anyway, if you have one, it should be complete: Hence have the 'tii() as a pure virtual function'. To resolve the conflict rewrite that function in 'Derived' (forward to Base::tii).
Consider following hierarchy:
class Interface {
public:
virtual void foo() = 0;
};
class SubInterface: public Interface {
public:
virtual void bar() = 0;
};
class Base: public Interface {
public:
void foo() {};
};
class Impl: public SubInterface, public Base {
public:
void bar() {};
};
There are several sub interfaces which offer other methods in addition to foo().
There can be several implementing classes to a sub interface.
foo() is always implemented the same way.
Here is an example which simulates how these classes would be used:
int main() {
SubInterface* view1 = new Impl(); // Error! Interface::foo() is pure virtual within Impl
view1->foo();
view1->bar();
Interface* view2 = view1;
view2->foo();
}
Why can't the compiler see that Interface::foo() is implemented in Base which Impl inherits from?
I figured that I could implement foo() in Impl explicitly and delegate the call to Base like this:
class Impl: public SubInterface, public Base {
public:
void foo() {
Base::foo();
}
void bar() {};
};
However, I would have to do that for all classes which implement a sub interface, so this way isn't exactly ideal. Is there a better solution?
SubInterface and Base should inherit virtually from Interface otherwise you are creating ambiguity in form of the dreaded diamond
Basically, what happens is that Impl contains two 'instances' of Interface.
Here is why - follow the diagram:
I have 6 classes which all perform the same actions. I would like to move common behavior to a common [base] class.
There are actions to be performed on 6 separate objects. The six objects are located in derived classes. Intuitively, the private member objects would be accessed through the child (derived class) in the base class.
What is the C++ pattern I am looking for?
class Base
{
// Common behavior, operate on m_object
...
void Foo()
{
m_object.Bar();
}
};
class Derived1 : public Base
{
// No methods, use Base methods
private:
MyObject1 m_object;
}
class Derived2 : public Base
{
// No methods, use Base methods
private:
MyObject2 m_object;
}
The thing that is boxing me into this situation is MyObject1, MyObject2, etc offer Bar(), but don't share a common base class. I really can't fix the derivation because the objects come from an external library.
If they are introduced in the derived classes, then the base class cannot directly access them. How would the base class know that all derived classes have a specific member?
You could use virtual protected methods like so:
class my_base
{
protected:
virtual int get_whatever();
virtual double get_whatever2();
private:
void process()
{
int y = get_whatever();
double x = get_whatever2();
//yay, profit?
}
}
class my_derived_1 : my_base
{
protected:
virtual int get_whatever()
{
return _my_integer;
}
virtual double get_whatever2()
{
return _my_double;
}
}
Another possibility (if you want to call the base methods from the derived classes) is to simply supply the arguments to the base methods.
class my_base
{
protected:
void handle_whatever(int & arg);
};
class my_derived : my_base
{
void do()
{
my_base::handle_whatever(member);
}
int member;
};
C++ does and doesn't. It has a very powerful multiple inheritance support, so there is no super keyword. Why? Imagine that your base class is, say, inherited by another two classes, or even is a part of virtual inheritance hierarchy. In that case you can't really tell what super is supposed to mean. On the other hand, there are virtual methods, you can always have them in base class and implement in derived classes (that's what languages like Java do, except that they they don't have multiple class inheritance support). If you don't want to go with polymorphism, you can use something like this:
#include <cstdio>
template <typename T>
struct Base
{
void foo ()
{
std::printf ("Base::foo\n");
static_cast<T *> (this)->bar ();
}
};
struct Derived : Base<Derived>
{
void bar ()
{
std::printf ("Derived::bar\n");
}
};
int
main ()
{
Derived d;
d.foo ();
}
This is an extremely simple example - you can extend the above example with access control, friends, compile-time assertions etcetera, but you get the idea.
Have you considered not using inheritance?
class FooBar
{
MyObject m_object;
public:
FooBar(MyObject m): m_object(m) {}
//operate on different m_objects all you want
};
What about deriving your six separate objects from a common base class? Then you can declare virtual methods in that base class to create your interface, and then implement them in the derived object classes.
Maybe you just need a template instead of superclass and 6 derived classes?
It seems that you need to access not the parent's, but child's field. You should do it by introducing an abstract method:
class ParentClass
{
public:
void f();
protected:
virtual int getSomething() = 0;
};
ParentClass::f()
{
cout << getSomething() << endl;
}
class DerivedClass : public ParentClass
{
protected:
virtual int getSomething();
}
DerivedClass::getSomething() { return 42; }
If you need to access parent's method, just use ParentClass::method(...):
class ParentClass
{
public:
virtual void f();
};
class DerivedClass : public ParentClass
{
public:
virtual void f();
};
void DerivedClass::f()
{
ParentClass::f();
}
class Base {
public:
Base(){ }
virtual void Bfun1();
virtual void Bfun2();
};
class Derv : public Base {
public:
Derv(){ }
void Dfun1();
};
Is there a difference between above definitions and the below ones ? Are they same ? if not how both are the different functionally ?
class Base {
public:
Base(){ }
void Bfun1();
void Bfun2();
};
class Derv : public virtual Base {
public:
Derv(){ }
void Dfun1();
};
They are completely different. The first set defines Bfun1 and Bfun2 as virtual function, that allows overriding them in the derived class and call those in the derived class through a base class pointer:
// assume you've overridden the functions in Derived
Base* base_ptr = new Derived;
base_ptr->Bfun1(); // will call function in derived
The second set, however, they're just normal functions. Instead, you declared the base class to be virtual, which has many implications you best read about in a good C++ book or search through the SO questions, I think we have one on that topic.