Can I have a virtual function in the base class and some of my derived classes do have that function and some don't have.
class A{
virtual void Dosomething();
};
class B : public A{
void Dosomething();
};
class C : public A{
//Does not have Dosomething() function.
};
From one of my c++ textbook:
Once a function is declared virtual, it remains virtual all the way down the inheritance, even if the function is not explicitly declared virtual when the derived class overrides it.
When the derived class chooses not to override it, it simply inherits its base class's virtual function.
Therefore to your question the answer is No. Class c will use Class A's virtual function.
Derived classes do not have to implement all the virtual functions, unless it is a pure virtual function. Even in this case, it will cause an error only when you try to instantiate the derived class( without implementing the pure virtual function ).
#include <iostream>
class A{
public :
virtual void foo() = 0;
};
class B: public A{
public :
void foo(){ std::cout << "foo" << std::endl;}
};
class C: public A{
void bar();
};
int main() {
//C temp; The compiler will complain only if this is initialized without
// implementing foo in the derived class C
return 0;
}
I think the closest you might get, is to change the access modifier in the derived class, as depicted below.
But, I would consider it bad practice, as it violates Liskov's substitution principle.
If you have a situation like this, you might need to reconsider your class design.
#include <iostream>
class A {
public:
virtual void doSomething() { std::cout << "A" << std::endl; }
};
class B : public A {
public:
void doSomething() override { std::cout << "B" << std::endl; };
};
class C : public A {
private:
void doSomething() override { std::cout << "C" << std::endl; };
};
int main(int argc, char **args) {
A a;
a.doSomething();
B b;
b.doSomething();
C c;
//c.doSomething(); // Not part of the public interface. Violates Liskov's substitution principle.
A* c2 = &c;
c2->doSomething(); // Still possible, even though it is private! But, C::doSomething() is called!
return 0;
}
Related
I know there are many questions out there concerning MI, however, none seemed to answer my question. I have the following minimal example:
#include <iostream>
struct Base{
virtual void foo() = 0;
};
struct A : public virtual Base{
void foo(){
std::cout << "A::foo()" << std::endl;
}
void foo( int a){
std::cout << "A::foo(int a)" << std::endl;
}
};
struct B : public virtual Base{
virtual void foo( int a ) = 0;
};
struct C : public B,public A{
using A::foo;
};
int main( int argc, char* argv[]){
C c;
c.foo();
c.foo( 1 );
}
where Base, and B are entirely virtual classes and A provides all the implementation. However, the code does not compile but instead gives me the following error message
mh.cpp: In function ‘int main(int, char**)’:
mh.cpp:22:11: error: cannot declare variable ‘c’ to be of abstract type ‘C’
C c;
^
mh.cpp:17:12: note: because the following virtual functions are pure within ‘C’:
struct C : public B,public A{
^
mh.cpp:15:22: note: virtual void B::foo(int)
virtual void foo( int a ) = 0;
The behaviour I desire can be achieved by extending class C to
struct C : public B,public A{
using A::foo;
void foo( int a ){
A::foo( a );
}
};
However, I'd prefer not adding this redundant method. Is there some way I can achieve that result?
A::foo(int) can't override B::foo(int) unless A derives from B.
So, if you don't want to create the forwarding override in C, your alternatives are:
move the foo(int) pure virtual overload into Base
make A derive from B
restructure your interfaces so you don't need diamond-shaped virtual inheritance in the first place
No, if you inherit from a pure virtual class and you want to use this derived class (declare object of that type, not a pointer), you must implement all its pure virtual methods.
In the same manner you could ask the following:
class A
{
public:
virtual void foo()=0;
virtual void hello()=0;
}
class B: public A
{
public:
void myFoo();
void hello() { std::cout << "Hello!"; }
}
In class B, I don't want to use A::foo() but only B::myFoo() what should I do?
In such case you either need to provide some dummy implementation for the pure virtual function or review again your design... probably you should not inherit from A.
Similar thing is in your case. Probably your class C should not inherit from class B.
Just replace your single line as below.
Derived C only from A.
Your code
struct C : public B,public A{
using A::foo;
};
Replace above code with below code,
struct C : public A{
using A::foo;
};
Consider a base class class Base which has a function virtual void foo(void). This function is implemented in Base; i.e. is not pure virtual.
Is there a pattern I can use which when inheriting from this class, i.e. class Child : public Base, compels me to override foo?
Other than making it a pure virtual function, there is no way to make the override required.
Note that the fact that a function is marked pure virtual does not mean that it cannot have an implementation in the base class - it means only that the derived class must override it.
struct Base {
virtual void foo() = 0; // foo() is pure virtual
};
struct Derived : public Base {
void foo() { // Derived overrides the pure virtual
cout << "Hello ";
Base::foo(); // Call the implementation in the base
cout << endl;
}
};
void Base::foo() {
cout << " world";
}
int main() {
Derived d;
d.foo();
return 0;
}
This prints "Hello world", with the "world" part coming from the implementation in the base class.
Demo.
C++11 introduced the override keyword to help with this:
struct Base
{
void foo();
};
struct Derived : Base
{
void foo() override; // error! Base::foo is not virtual
};
However you can not write this in Base itself to get the same effect; i.e. there is no mustoverride specifier. Ultimately, it is none of Base's business as to what derived classes do or don't override.
You can keep Base abstract whilst providing a "default" definition for your pure virtual functions:
struct Base
{
virtual void foo() = 0;
};
void Base::foo() {}
struct Derived : Base {}; // error! does not override Base::foo
struct Derived2: Base
{
virtual void foo() override
{
Base::foo(); // invokes "default" definition
}
};
This will be an acceptable solution if you are content for the entire base type to be rendered uninstantiable.
A pure-virtual member function can still have a body. The only caveat is that it must be defined outside the class definition. This is perfectly legal C++:
#include <iostream>
struct Base
{
virtual void foo() const = 0;
};
void Base::foo() const
{
std::cout << "Base!\n";
}
struct Derived : Base
{
// Uncomment following line to remove error:
//virtual void foo() const override { std::cout << "Derived\n"; Base::foo(); }
};
int main()
{
Derived d;
d.foo();
}
Live example
Notice that this makes Base an abstract class in all respects, i.e. it's impossible to instantiate Base directly.
Yes, actually there is:
#include <iostream>
class Base
{
public:
virtual void someFun() {std::cout << "Base::fun" << std::endl;}
virtual ~Base() {}
};
class AlmostBase : public Base
{
public:
virtual void someFun() = 0;
};
class Derived : public AlmostBase
{
public:
virtual void someFun() {std::cout << "Derived::fun" << std::endl;}
};
int main()
{
Derived *d = new Derived();
d->someFun();
delete d;
}
If you uncomment the someFun from Derived the compiler will complain ...
You introduce an intermediary class AlmostBase which has the function as pure virtual. This way you can have Base objects too, and the only drawback now is that all your classes will need to inherit from the intermediary base.
you can make the base method throw an exception when called, then the class must override it to avoid the parent execution.
this is used in the MFC FrameWork for example
// Derived class is responsible for implementing these handlers
// for owner/self draw controls (except for the optional DeleteItem)
void CComboBox::DrawItem(LPDRAWITEMSTRUCT)
{ ASSERT(FALSE); }
void CComboBox::MeasureItem(LPMEASUREITEMSTRUCT)
{ ASSERT(FALSE); }
int CComboBox::CompareItem(LPCOMPAREITEMSTRUCT)
{ ASSERT(FALSE); return 0; }
those methods must be inherited if the control is owner drawn it is responsible for the measuer, draw,... if you missed it while you are testing the function you will get an assert or exception with useful information thrown.
I have a problem that I have not yet tested/compiled and wondering if it is possible and if it is bad design?
My Problem:
I want to have an abstract base class A and a abstract derived class B.
I realize if this is possible I will have a number of pure virtual member functions in each class and also I will not be able to initialize these objects, but that is a given for abstract classes.
In my design I will have another derived class C which I would then initialize - class C would be derived from class B.
I would have something that looked like this
class C
^
|
abstract class B
^
|
abstract base class A
My Question:
Is this possible first of all? I would suspect so, but not declaring the pure virtual functions in A in class B may be troublesome?
e.x.
class A {
public:
virtual void test()=0;
};
class B: public A {
public:
virtual void test()=0;
virtual void anotherTest()=0;
};
Is the above okay?
Is this bad c++ design? In future I will have derived classes from A so it would be nice to have this design.
Nothing wrong with it, and it will certainly work. Example follows
stefanos-imac:dftb borini$ more test.cpp
#include <iostream>
class A {
public:
A(void) { std::cout << "A" << std::endl; }
virtual void method1() = 0;
};
class B : public A {
public:
B(void) : A() { std::cout << "B" << std::endl; }
virtual void method2() = 0;
};
class C : public B {
public:
C(void) : B() { std::cout << "C" << std::endl; }
virtual void method1() { std::cout << "method1" << std::endl; }
virtual void method2() {std::cout << "method2" << std::endl; }
};
int main() {
C c;
c.method1();
c.method2();
}
stefanos-imac:dftb borini$ ./a.out
A
B
C
method1
method2
Thank you for reminding me that I can still type basic C++.
Starting from this code:
class Base{
public:
virtual void foo(){....}
};
class Derived{
public:
void foo(){....}
};
If d is a Derived object, can I in some way invoke the foo method defined in the Base class for this object?
Edit: i mean from the outside, such that d.foo() binds to Base::foo()
Specify it explicitly in the call.
#include <iostream>
class Base{
public:
virtual void foo(){
std::cout << "Base" << std::endl;
}
};
class Derived : public Base{
public:
void foo(){
std::cout << "Derived" << std::endl;
}
};
int main()
{
Derived d;
d.Base::foo();
return 0;
}
Just qualify the call (Assuming that Derived actually inherits from Base, which in your code it doesn't):
Derived d;
d.Base::foo();
Now, while this is doable, it is also quite questionable. If the method is virtual, it is meant to be overridden and users should not call a particular override, but the final-overrider, or else they risk breaking class invariants all the way through.
Consider that the implementation of Derived::foo did some extra work needed to hold some invariant, if users call Base::foo that extra work would not be done and the invariant is broken, leaving the object in an invalid state.
To call it from outside code, you can still explicitly qualify the name in the call:
#include <iostream>
#include <vector>
struct base {
virtual void do_something() { std::cout << "Base::do_something();\n"; }
};
struct derived : public base {
virtual void do_something() { std::cout << "derived::do_something();\n"; }
};
int main() {
derived d;
d.base::do_something();
return 0;
}
If you're using a pointer to the object, you'd change that to d->base::do_something();.
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.,