An abstract class has internal virtual functions.
Can an abstract class have internal virtual classes to be implemented later?
I tried the following:
#include <bits/stdc++.h>
using namespace std;
class C1 {
public:
class Child {
int tmp;
virtual int getint() = 0;
};
virtual Child getChild() = 0;
};
class C2: public C1 {
public:
class Child {
int getint()
{
return 10;
}
} c;
Child getChild()
{
return c;
}
};
int main() { return 0; }
Child is an abstract class which will be overrode in derived classes. And I hope the implemented Child can be used to define a function.
However, I got an error:
invalid abstract return type for member function 'virtual C1::Child C1::getChild()'
Can't I implement an internal abstract class in derived classes, just like implementing a virtual function?
In the present code, class C1::Child and class C2::Child have no inheritance relationship. Hence they are totally unrelated classes. Even if you relate them with inheritance, then also getChild() cannot return Child (value). It can return either Child& (reference) or Child* (pointer) to form a valid virtual methods with covariance. Refer: C++ virtual function return type
Such errors are easily caught by using override specifier available in C++11.
Without knowing the exact context of what you are trying to achieve, the possible code should look like this:
class C1 {
// ... same
virtual Child& getChild() = 0;
// ^^^^^^ reference
};
class C2 : public C1 {
// ^^^^^^ did you miss this?
public:
class Child : public C1::Child {
// ^^^^^^^^^ inheritance
int getint() override { return 10; }
} c;
Child& getChild() override { return c; }
};
Also your below statement seems confusing:
"Child is a abstract class, which will be implemented later,"
Like virtual methods, the classes don't have such runtime relationships.
The best meaning of "implementing later" in the context of class is -- implementing it outside the body of the enclosing class, such as:
class Outer { public: class Inner; };
// ...
class Outer::Inner { ... };
Theoretically, Abstract Classes are used for creating Interfaces. Using Interfaces, clients demand the required functionality. By defining/implementing Interfaces, servers fulfill the client's functionality. Interface/Abstract Class are simply blueprint of requirement/agreement between client and server. The classes which implement the Interface/Abstract Class or fulfills the functionality requirement can be instantiated. So there can be many implementation of the same Interface/Abstract Class. Now in order to access all these different implementation of the same Interface/Abstract Class seamlessly at different point of time, we need a generalized way. And this generalized way is via pointer(*) or reference(&) to the underlying Interface\Abstract Class.
In your code C1::Child is an anAbstract Class or Interface.
So, C1::getChild() can return an implementation of the Interface/Abstract C1::Child. But it cannot return an instance of the Interface/Abstract C1::Child itself as per above theoretical explanation. And hence the error.
Proper way to declare C1::getChild() would be:
virtual C1::Child* getChild() = 0; or
virtual C1::Child& getChild() = 0;
Also, C1::Child can be simply seen as a class inside namespace C1, since class is also a kind of namespace with some restriction.
From your post you seem to be confusing things. I suggest you get a re-read on abstract classes and try some simple examples yourself.
Child is a abstract class, which will be implemented later, And I hope
the implemented Child can be used to define a function.
A pure virtual method (virtual int getint() = 0; in your example) is not meant to be implemented "later". It's meant to be implemented by an override method in a derived class.
E.g. if you have
class Child {
virtual int getint() = 0;
};
you cannot do
class Child {
virtual int getint() { return 10; }
};
nor
int Child::getint() { return 10; }
at a later time.
What you can do is:
class Derived : public Child
{
int getint() override { return 10; }
};
Related
Suppose we have a base class Base with a public interface, and some protected methods that are used to support the public interface. Simplified example:
class Base {
protected:
virtual int helper() const = 0;
public:
virtual void do_work() {
//By default, just call the helper. Descendants can customize behaviour.
int x = helper();
do_something_with_an_int(x);
}
};
And suppose we have some descendants DerivedA, DerivedB, DerivedC ... that implement this interface.
The reason I want to split up the work in two functions (rather than just use do_work to do everything) is because I want to have a special descendant that might look something like this:
class DescendantWrapper : Base {
Base *impl;
int x;
protected:
int helper() const override {
x += impl->helper();
}
public:
void do_work() override {
helper();
if(some_internal_condition()) {
do_some_other_thing_with_an_int(x);
} else {
x = 0;
}
}
};
The intention is to allow DescendantWrapper to wrap any descendant of Base, and take the place of that descendant in some other code. Of course, the other code would not be aware that its descendant of Base has been wrapped.
The problem is that a derived class (in this example, DescendantWrapper) cannot call a protected method on an instance of its parent class (in this example, Base::helper()).
One solution is to specifically declare DescendantWrapper as a friend of Base. However, this means that other users of this code couldn't create their own descendant wrappers. Does anyone know an alternative to friend functions in this scenario?
I have a base class with a bunch of functionality and a derived class that extends that class but there are a few methods in the base class that don't make sense on the derived class.
Is it possible to do something to prevent these method(s) from being used by the derived class?
Class A
{
...
public:
void SharedMethod();
virtual void OnlyMakesSenseOnA();
}
Class B : public Class A
{
...
public:
void OnlyMakesSenseOnB();
}
The following obviously doesn't work but is it possible to do something similar so that the compiler doesn't allow a certain base class method to be called?
Class B : public Class A
{
...
public:
void OnlyMakesSenseOnA() = 0;
}
No, and this is completely wrong. If the member function is not callable in the derived type you are breaking the Liskov Substitution Principle. Consider whether this is the correct inheritance relationship. Maybe you want to extract SharedMethod to a real base and provide two separate unrelated A and B types.
This isn't as easy of an answer as I had hoped, but a coworker suggested that this situation is an indication of bad design and that I should re-think my inheritance structure by adding a new base class that only contains common functionality:
Class Base
{
...
public:
void SharedMethod();
}
Class A : public Base
{
...
public:
void OnlyMakesSenseOnA();
}
Class B : public Base
{
...
public:
void OnlyMakesSenseOnB();
}
Edit: Thanks to #David for providing a name for the rule that I'm trying to break. B is not a "Behavioural Subtype" of A because it fails the "counterfeit test". Therefore, deriving B from A violates the Liskov Subtitution Principle.
According to this slide deck, the counterfeit test is as follows:
Suppose I promise to deliver you an object of class T, but
instead I give you an object x of class S.
You can subject x to any series of method calls you like
(chosen from T’s signature).
If x behaves in a way that is not expected of a T object,
then you know it is a counterfeit, x has failed the test.
If all S objects always pass every counterfeit test, then S is
a behavioural subtype of T.
You could also just throw an exception if the invalid method is called on the derived class. It doesn't catch the bug at compile time but at least it prevents it from accidentally being used a runtime.
Class B : public Base
{
...
public:
void OnlyMakesSenseOnA() { throw Exception(); }
}
Yes, it's possible and quite simple, if we're talking about an external call. You can hide parent's method with private methods of derived class. Works with the static methods as well.
Tested on cpp 98, 11, 14. Try yourself in C++ shell.
class Base{
public:
void methodBase(){};
static void methodBaseStatic(){};
};
class Derived : public Base{
//private: //(private on default)
void methodBase(){};
static void methodBaseStatic(){};
};
Normal operation:
int main()
{
Base b;
b.methodBase();
Base::methodBaseStatic();
Derived d;
return 0;
}
Compilation error
int main()
{
Derived d;
d.methodBase();
Derived::methodBaseStatic();
return 0;
}
Let's say I have pure abstract class IHandler and my class that derives from it:
class IHandler
{
public:
virtual int process_input(char input) = 0;
};
class MyEngine : protected IHandler
{
public:
virtual int process_input(char input) { /* implementation */ }
};
I want to inherit that class in my MyEngine so that I can pass MyEngine* to anyone expecting IHandler* and for them to be able to use process_input.
However I don't want to allow access through MyEngine* as I don't want to expose implementation details.
MyEngine* ptr = new MyEngine();
ptr->process_input('a'); //NOT POSSIBLE
static_cast<IHandler*>(ptr)->process_input('a'); //OK
IHandler* ptr2 = ptr; //OK
ptr2->process_input('a'); //OK
Can this be done via protected inheritance and implicit casting?
I only managed to get:
conversion from 'MyEngine *' to 'IHandler *' exists, but is inaccessible
Since I come from C# background, this is basically explicit interface implementation in C#.
Is this a valid approach in C++?
Additional:
To give a better idea why I want to do this, consider following:
Class TcpConnection implements communication over TCP, and in its constructor expects pointer to interface ITcpEventHandler.
When TcpConnection gets some data on a socket, it passes that data to its ITcpEventHandler using ITcpEventHandler::incomingData, or when it polls for outgoing data it uses ITcpEventHandler::getOutgoingData.
My class HttpClient uses TcpConnection (aggregation) and passes itself to TcpConnection constructor, and does processing in those interface methods.
So TcpConnection has to implement those methods, but I don't want users using HttpClient to have direct access to ITcpEventHandler methods (incomingData, getOutgoingData). They should not be able to call incomingData or getOutgoingData directly.
Hope this clarifies my use case.
Deriving with protected makes the members of the base class inaccessible through a pointer to the derived class, and disallows the implicit conversion.
It seems to me that what you want is not to forbid access through the base class (interface), but rather through the derived class (concrete implementation):
class IHandler
{
public:
virtual int process_input(char input) = 0; //pure virtual
virtual std::string name() { return "IHandler"; } //simple implementation
};
class MyEngine : public IHandler
// ^^^^^^
{
protected: // <== Make the functions inaccessible from a pointer
// or reference to `MyEngine`.
virtual int process_input(char input) { return 0; } //override pure virtual
using IHandler::name; //use IHandler version
};
Here, in the derived class you basically override the visibility of the process_input function, so that clients can only call them through a pointer or reference to the base class.
This way you will make this impossible:
MyEngine* ptr = new MyEngine();
ptr->process_input('a'); // ERROR!
std::cout << ptr->name(); // ERROR!
But this will be possible:
IHandler* ptr = new MyEngine();
ptr->process_input('a'); // OK
std::cout << ptr->name(); // OK
In C++ protected and private inheritance serve the use of inheritance of the implementation. This is, you define a class with methods, a template class for example and when you want to use its functionality but not its interface, you inherit protected or private. So actually your base class would need to define the methods you want to use in the sub-class.
Here is a link on this topic. It really is difficult, I agree.
It's slightly hard to understand the real goal you hope to achieve here, because whether you call the method on the parent or child, as long as it's virtual the same one will be called.
That said you have a couple options.
You could make it so the user can't get a pointer (or object) of the child type by forcing a create call that returns an interface. Then you don't have to worry about artificial restrictions, they just can't get a child at all:
class Concrete : public Interface
{
public:
static Interface* create() { return new Concrete; }
private:
Concrete() { }
};
You could override the interface as protected as shown in a different answer.
You could utilize the non-virtual interface pattern to make the entire accessible public interface defined in the parent. Then it doesn't matter what object they have, they always get the public API from the interface class:
class Interface
{
public:
void foo() { foo_impl(); }
private:
virtual void foo_impl() = 0;
};
class Concrete
{
private:
virtual void foo_impl() { }
};
A common scenario in my code is that I got a functor that is used by many classes in a hierachy.
To make it accessible by all classes and stay DRY, I usually define it as a protected inner struct of my base class like that:
class Base
{
protected:
struct CommonFunctor
{
bool operator()()
{
return true;
}
};
};
class DerivedA : public Base
{
void FooA()
{
bool test = CommonFunctor()();
}
};
class DerivedB : public Base
{
void FooB()
{
bool test = CommonFunctor()();
}
};
I don't like that solution because it clutters my base class with many small functors, that are internal only and even if they are not accessible to the public, they decrease readability of my base class.
Do you know any other solutions for this scenario?
Just implement your functors in new files (BaseClassFunctors.cpp + BaseClassFunctors.h). Put them inside your namespace with an optional subnamespaces (e.g. namespace main.internal).
Now you include the header file in any derived classes you want, without cluttering the base class header.
As much as I (and, apparently, everyone else) hate multiple inheritance, it would come in handy here.
Just create a second class that contains all your functors and in your child classes derived from Base, inherit both Base and this new class.
You can just implement the functor elsewhere and still keep it as a member of the Base:
class Base
{
protected:
struct CommonFunctor;
};
struct Base::CommonFunctor
{
bool operator()()
{
return true;
}
};
I have a class template where some methods are defined as virtual to give the ability for the user of my class to give an implementation for them in his derived class. Note that in my template class there is some non-virtual methods that makes use of the virtual one (a virtual class that should return a value is called in a non-virtual class).
Can you give me a simple example of a correct code where the virtual method of the parent class should return a value (but it's implementation is provided in a child class) and the value returned by the virtual method in the parent class is used in other methods of that class. Because I saw somewhere (for example here: Safely override C++ virtual functions) that this can cause some problems and the user defined method will note override the virtual method of the parent class.
Note: I program with Code::Blocks using g++ compiler.
EDIT: as requested here a simple example of what I want:
template<typename T>
class parent {
public:
// Public methods that user can call
int getSomething(T t);
void putSomething(T t, int x);
// public method that user should implement in his code
virtual float compute(T t) { }
// protected or private methods and attributes used internally by putSomething ...
float doComplexeThings(...); // this can call
};
The method compute() should be implemented by the user (the child class). However, this method compute() is called by putSomething() and doComplexeThings() for example.
If you can use C++11 features in your compiler then overrides can be tagged as so with the override special identifier:
float compute() override;
The above line in a derived class will cause a compiler error as the function does not override a member function in the base (incorrect signature, missing argument). But note that this must be done in each derived class, it is not a solution that you can impose from the base class.
From the base class you can only force the override by making the function pure virtual, but that changes the semantics. It does not avoid problems while overriding, but rather forces overriding in all cases. I would avoid this approach, and if you are to follow it and there is a sensible implementation for the base type, make the function virtual and provide a definition so that your derived classes's implementation can just call the functions the base type (i.e. you force the implementation, but in the simplest cases it will just forward the call to the parent)
You just have to make sure that the methods have the same signature (including const/mutable modifiers and argument types). You can use a pure virtual definition to provoke compiler errors if you fail to override the function in a subclass.
class parent {
public:
// pure virtual method must be provided in subclass
virtual void handle_event(int something) = 0;
};
class child : public parent {
public:
virtual void handle_event(int something) {
// new exciting code
}
};
class incomplete_child : public parent {
public:
virtual void handle_event(int something) const {
// does not override the pure virtual method
}
};
int main() {
parent *p = new child();
p->handle_event(1); // will call child::handle_event
parent *p = new incomplete_child(); // will not compile because handle_event
// was not correctly overridden
}
This question is asked in 2013. It's pretty old but I found something new which doesn't exist in the answers.
We need to understanding three concept is overload, overwrite, and hide.
Short answer, you want to overload the inheritance function from base class.
However, overload is the mechanism to add multiple behavior for function which needs all these functions under the same scale. But the virtual function is in the Base class obviously.
class A {
public:
virtual void print() {
cout << id_ << std::endl;
}
private:
string id_ = "A";
};
class B : A {
public:
using A::print;
void print(string id) {
std::cout << id << std::endl;
}
};
int main(int argc, char const *argv[]) {
/* code */
A a;
a.print();
B b;
b.print();
b.print("B");
return 0;
}
Add using A::print; in your derive class will do the work!
Though I don't feel it's a good idea since the philosophy behind the overload and inheritance is different, it may not a good idea to nest them together.