I want to understand the following c++ concept. class_a is abstract class and as per abstract class concept we cannot create any instance of it.
i have used the initlization list and abstract class as well but never used following concept.
In the code ,the initlization list of class_b, class_a is initlized. I want to understand what is meaning of initlizing it in the initilization list.
class_b::class_b(int val):nameA::class_a()
in fileA.cpp
namespace nameA
{
class class_a
{
public:
virtual ~class_a(){};
virtual void process()=0;
};
}
in fileb.h file
namespace nameB
{
class class_b : public nameA::class_a
{
public:
class_b(int val);
}
}
in fileb.cpp file
namespace nameB
{
class_b::class_b(int val)
:nameA::class_a() //Want to understand this line...
}
It would be more clear with a slightly richer example. Because if the abstract base class has neither attributes nor methods it is harder to see how it can be initialized.
class NamedProcessor {
std::string name; // a private attribute
public:
NamedProcessor(const std::string &name) : name(name) {}
virtual ~NamedProcessor() {}
// a pure virtual method to make the class abstract
virtual void process() = 0;
std::string getName() {
return name;
}
};
class Doubler : public NamedProcessor {
int value; // a private attribute
public:
Doubler(int initial = 1) : NamedProcessor("Doubler") {
reset(initial);
}
void reset(int initial) {
value = initial;
}
int getValue() {
return value;
}
// the concrete implementation
void process() {
value *= 2;
}
};
int main() {
// Compiler would croak witherror : variable type 'NamedProcessor' is an abstract class
// NamedProcessor wrong("Ill formed");
Doubler doubler;
std::cout << doubler.getName() << "\n"; // name has been initialized...
return 0;
}
Here the abstract class holds an attribute which will be available to subclasses. And this attribute has to be set at construction time because there is no public setter for it. The language has to provide a way to initialize the abstract subclass, meaning not building an object, but initializing a sub-object - here setting the name.
By deriving, every class_b object will contain a class_a sub-object.
Even if you cannot instanciate an object of type class_a, there may be a need of initializing this sub-object. Consider that an abstract class can also have members.
If you have an abstract class in terms of an interface (like in Java), this abstract class obviously needs no initialization. Nevertheless it would get a (empty) default constructor in C++, that you can call explicitly in the initialization list. (If you do not call it explicitly, it will be called implicitly.)
If class is abstract it doesn't mean that it can't have any constructor. It means that you can't use it for creating an independent object.
So here is classic inheritance mechanism:
You creating a child_class object
It calls a child_class() constructor
child_class() constructor calls base_class() constructor to guarantee that fields of base_class are built correct
Then executes child_class() constructor for the rest child_class fields
In your example you call class_a() constructor by yourself, but it will be called anyway. So in sum, it's not about abstract class, it's all about simple inheritance.
You need to have some mechanism for initializing class_a fields if they exists, that's why you can call class_a() constructor even if it's abstract class, otherwise inheritance mechanism just useless.
Related
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;
}
I want to make a class that passes a member object to its parent for initialization. The below code shows what I'm trying to do.
class TQueueViewerForm1 : public TQueueViewerForm
{
private: // User declarations
DOMMsgCollectionEditorImpl m_collection;
public: // User declarations
__fastcall TQueueViewerForm1(TComponent* Owner);
};
__fastcall TQueueViewerForm1::TQueueViewerForm1(TComponent* Owner)
: TQueueViewerForm(Owner, m_collection)
{
}
This doesn't seem to work however. It looks like the constructor TQueueViewerForm() is being called before m_collection is initialized. This crashes the program since TQueueViewerForm() tries to use the uninitialized object.
So... what are my choices here? Ideally I would like to just initialize m_collection before the parent class is initialized somehow.
You have to remember the order of operations with inheritance. When you construct an instance of a class, first the base component gets constructed (i.e. your base class constructor gets run to completion); then, your class' members are initialized, and finally, your class' constructor gets run.
In this case, you're passing somewhat-random memory to your base class before it ever got initialized.
A derived class's parent constructor will always be called before the child's constructor. One option you have is to put the initialization code that you're trying to execute in a separate function in the parent class and call that function in the derived class's constructor.
class CollectionHolder {
public:
DOMMsgCollectionEditorImpl m_collection;
};
class TQueueViewerForm1 :
private CollectionHolder, // important: must come first
public TQueueViewerForm {
};
A bit too subtle for my taste. Personally, I'd try to find a design that doesn't require me to perform such gymnastics.
You can pass parameters to a base classes constructor using the initialization list of the derived classes constructor.
class Parent
{
public:
Parent(std::string name)
{
_name = name;
}
std::string getName() const
{
return _name;
}
private:
std::string _name;
};
//
// Derived inherits from Parent
//
class Derived : public Parent
{
public:
//
// Pass name to the Parent constructor
//
Derived(std::string name) :
Parent(name)
{
}
};
void main()
{
Derived object("Derived");
std::cout << object.getName() << std::endl; // Prints "Derived"
}
I've written an abstract class (with pure virtual functions), and I'd like to have a method accept one such class as a parameter. Given that the class is abstract, I understand that I couldn't pass an abstract class to any method, but why can't I pass a subclass of an abstract class to that method? How do I specify that a parameter should be any of the subclasses of a specified baseclass? This is all in C++.
You need to specify the parameter as a pointer (or reference), e.g. Abstract * rather than Abstract. If Derived inherits from Abstract, you can pass a variable of type Derived * when Abstract * is expected, but you can't in general pass one of type Derived when Abstract is expected.
Then you use polymorphism in C++.
Given any base class:
struct Base{};
and its subclasses:
struct SubClassA : public Base(){};
struct SubClassB : public Base(){};
If you declare:
void MyFunctionReference(Base&){};
void MyFunctionPointer(Base*){};
You can then call:
{
SubClassA a;
SubClassB b;
MyFunctionReference(a); // by reference
MyFunctionPointer(&b); // by pointer address
}
You can indeed do this, observe:
Pure abstract class:
class Abstract {
public:
virtual void foo() = 0;
};
Child of overrides member function:
class AbstractImpl : public Abstract {
public:
void foo() override { std::cout << "Hi from subclass\n"; }
};
Now we declare a method that takes a reference type of the abstract class
void somefunc(Abstract &ab) {
ab.foo();
}
Finally in main we instantiate the child class parameter
int main() {
AbstractImpl test;
somefunc(test); // prints Hi from subclass
return 0;
}
Source: https://stackoverflow.com/a/11422101/2089675
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() { }
};
Please look at this code. It just reflects basic concept of what I want to do:
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
/* Some code I want to reuse */
Redefined();
}
virtual ~Base() {}
void Redefined() { val = 10; }
int val;
};
class Derived : public Base
{
public:
Derived() : Base() {}
~Derived() {}
void Redefined() { val = 25; }
};
int main()
{
Base* check = new Derived();
cout << check->val << endl;
system("pause");
return 0;
}
I want the val property of check object to be 25 instead of 10.
As you can see I have two classes. Base class constructor have some complex functionality, which I want Derived class to have in it's constructor as well. How can I change derived function Redefined so that I won't have to rewrite Derived constructor completely (in fact just copy-pasting the whole base class constructor code and replacing one single line of code - updated version of Redefined function)?
You can't really override a function that way. Normally you could use a virtual functions, but that doesn't work the way you want in the constructor.
A better way is to pass the value you want to the Base constructor:
class Base
{
public:
Base(int init_val = 10)
{
/* Some code I want to reuse */
val = init_val;
}
virtual ~Base() {}
int val;
};
class Derived : public Base
{
public:
Derived() : Base(25) {}
~Derived() {}
};
That way any derived class can pass its choice of value to the base class.
Based on comments above:
I would actually think that the correct solution is to have a "interface" type baseclass (that is, a baseclass with pure virtual functions, and the derived class actually implements the correct behaviour), and then let each class deal with constructing its own DirectX buffers. You may find that you need, say, 2-3 different derived classes that construct buffers in different ways, and then derive from those the classes that actually do the real work. I hope that makes sense.
Alternatively, you would be passing enough parameters to the base-class, such that the buffers can be constructed. But I think the first suggestion is a better choice.