Is Abstract class an example of Abstract data type? - c++

I'm getting confused by these two. What I learned is that Abstract data type is a mathematical model for data type, where it specifies the objects and the methods to manipulate these objects without specifying the details about the implementation of the objects and methods. Ex: an abstract stack model defines a stack with push and pop operations to insert and delete items to and from the stack. We can implement this in many ways, by using linked lists, arrays or classes.
Now, coming to the definition of abstract class, its a parent class which has one or more methods that doesn't have definition(implementation?) and cannot be instantiated (much like we can't implement an abstract stack as it is, without defining the stack's underlying mechanism through one of the concrete data structures). For ex: if we have an abstract class called Mammal which includes a function called eat(), we don't know how a mammal eats because a mammal is abstract. Although we can define eat() for a cow which is a derived class of mammal. Does this mean that mammal serves as an adt and cow class is an implementation of the mammal adt?
Correct me if I'm wrong in any way. Any kind of help would be really appreciated.

Abstract data type is a mathematical model for data type...
Now, coming to the definition of abstract class...
You need to distinguish between theoretical mathematical models and a practical implementation techniques.
Models are created by people in order to reason about problems easily, in some comprehensible, generalized way.
Meanwhile, the actual code is written in order to work and get the job done.
"Abstract data type" is a model. "Abstract class" is a programming technique which some programming languages (C++, C#, Java) support on the language level.
"Abstract data type" lets you think and talk about the solution of a problem, without overloading your brain with unnecessary (at this moment) implementation details. When you need a FIFO data structure, you say just "stack", but not "a doubly-linked list with the pointer to the head node and the ability to...".
"Abstract class" lets you write the code once and then reuse it later (because that is the point of OOP - code reuse). When you see that several types have a common interface and functionality - you may create "an abstract class" and put the intersection of their functionality in inside, while still being able to rely on yet unimplemented functions, which will be implemented by some concrete type later. This way, you write the code once and when you need to change it later - it's only one place to make the change in.
Note:
Although, in C++ ISO Standard (at least in the draft) there is a note:
Note: The abstract class mechanism supports the notion of a general concept,
such as a shape, of which only more concrete variants, such as circle
and square, can actually be used.
but it is just a note. The real definition is:
A class is abstract if it has at least one pure (aka unimplemented) virtual function.
which leads to the obvious constraint:
no objects of an abstract class can be created except as subobjects of
a class derived from it
Personally, I like that C++ (unlike C# and Java) doesn't have the keyword "abstract". It only has type inheritance and virtual functions (which may remain unimplemented). This helps you focus on a practical matter: inherit where needed, override where necessary.
In a nutshell, using OOP - be pragmatic.

The term "abstract data type" is not directly related to anything in C++. So abstract class is one of the potential implementation strategies to implement abstract data types in the given language. But there are a lot more techniques to do that.
So abstract base classes allow you to define a set of derived classes and give you the guarantee that all interfaces ( declarations ) have also an implementation, if not, the compiler throws an error, because you can't get an instance of your class because of the missing method definition.
But you also can use compile time polymorphism and related techniques like CRTP to have abstract data types.
So you have to decide which features you need and what price you want to pay for it. Runtime polymorphism comes with the extra cost of vtable and vtable dispatching but with the benefit of late binding. Compile time polymorphism comes with the benefit of much better optimizable code with faster execution and less code size. Both give you errors if an interface is not implemented, at minimum at the linker stage.
But abstract data types with polymorphism, independend of runtime or compile time, is not a 1:1 relation. Making things abstract can also be given by simply defining an interface which must be somewhere fulfilled.
In a short: Abstract data types is not a directly represented in c++ while abstract base class is a c++ technique.

Is Abstract class an example of Abstract data type?
Yes, but in C++, abstract classes have become an increasingly rare example of abstract data types, because generic programming is often a superior alternative.
Ex: an abstract stack model defines a stack with push and pop
operations to insert and delete items to and from the stack. We can
implement this in many ways, by using linked lists, arrays or classes.
The C++ std::stack class template more or less works like this. It has member functions push and pop, and it's implemented in terms of the Container type parameter, which defaults to std::deque.
For an implementation with a linked list, you'd type std::stack<int, std::list<int>>. However, arrays cannot be used to implement a stack, because a stack can grow and shrink, and arrays have a fixed size.
It's very important to understand that the std::stack has absolutely nothing to do with abstract classes or runtime polymorphism. There's not a single virtual function involved.
Now, coming to the definition of abstract class, its a parent class
which has one or more methods that doesn't have
definition(implementation?) and cannot be instantiated
Yes, that's precisely the definition of an abstract class in C++.
In theory, such a stack class could look like this:
template <class T>
class Stack
{
public:
virtual ~Stack() = 0;
virtual void push(T const& value) = 0;
virtual T pop() = 0;
};
In this example, the element type is still generic, but the implementation of the container is meant to be provided by a concrete derived class. Such container designs are idiomatic in other languages, but not in C++.
much like we can't implement an abstract stack as it is, without defining the stack's underlying mechanism through one of the concrete data structures
Yes, you couldn't use std::stack without providing a container type parameter (but that's impossible anyway, because there's the default std::deque parameter), and you cannot instantiate a Stack<int> my_stack; either.

Related

C++ typedef versus unelaborated inheritance

I have a data structure made of nested STL containers:
typedef std::map<Solver::EnumValue, double> SmValueProb;
typedef std::map<Solver::VariableReference, Solver::EnumValue> SmGuard;
typedef std::map<SmGuard, SmValueProb> SmTransitions;
typedef std::map<Solver::EnumValue, SmTransitions> SmMachine;
This form of the data is only used briefly in my program, and there's not much behavior that makes sense to attach to these types besides simply storing their data. However, the compiler (VC++2010) complains that the resulting names are too long.
Redefining the types as subclasses of the STL containers with no further elaboration seems to work:
typedef std::map<Solver::EnumValue, double> SmValueProb;
class SmGuard : public std::map<Solver::VariableReference, Solver::EnumValue> { };
class SmTransitions : public std::map<SmGuard, SmValueProb> { };
class SmMachine : public std::map<Solver::EnumValue, SmTransitions> { };
Recognizing that the STL containers aren't intended to be used as a base class, is there actually any hazard in this scenario?
There is one hazard: if you call delete on a pointer to a base class with no virtual destructor, you have Undefined Behavior. Otherwise, you are fine.
At least that's the theory. In practice, in the MSVC ABI or the Itanium ABI (gcc, Clang, icc, ...) delete on a base class with no virtual destructor (-Wdelete-non-virtual-dtor with gcc and clang, providing the class has virtual methods) only results in a problem if your derived class adds non-static attributes with non-trivial destructor (eg. a std::string).
In your specific case, this seems fine... but...
... you might still want to encapsulate (using Composition) and expose meaningful (business-oriented) methods. Not only will it be less hazardous, it will also be easier to understand than it->second.find('x')->begin()...
Yes there is:
std::map<Solver::VariableReference, Solver::EnumValue>* x = new SmGuard;
delete x;
results in undefined behavior.
This is one of the controversial point of C++ vs "inheritance based classical OOP".
There are two aspect that must be taken in consideration:
a typedef is introduce another name for a same type: std::map<Solver::EnumValue, double> and SmValueProb are -at all effect- the exact same thing and cna be used interchangably.
a class introcuce a new type that is (by principle) unrelated with anything else.
Class relation are defined by the way the class is "made up", and what lets implicit operations and conversion to be possible with other types.
Outside of specific programming paradigms (like OOP, that associate to the concept of "inhritance" and "is-a" relation) inheritance, implicit constructors, implicit casts, and so on, all do a same thing: let a type to be used across the interface of another type, thus defining a network of possible operations across different types. This is (generally speaking) "polymorphism".
Various programming paradigms exist about saying how such a network should be structured each attempting to optimize a specific aspect of programming, like the representation or runtime-replacable objects (classical OOP), the representation of compile-time replacable objects (CRTP), the use of genreric algorithial function for different types (Generic programming), teh use of "pure function" to express algorithm composition (functional and lambda "captures").
All of them dictates some "rules" about how language "features" must be used, since -being C++ multiparadigm- non of its features satisfy alone the requirements of the paradigm, letting some dirtiness open.
As Luchian said, inheriting a std::map will not produce a pure OOP replaceable type, since a delete over a base-pointer will not know how to destroy the derived part, being the destructor not virtual by design.
But -in fact- this is just a particular case: also pbase->find will not call your own eventually overridden find method, being std::map::find not virtual. (But this is not undefined: it is very well defined to be most likely not what you intend).
The real question is another: is "classic OOP substitution principle" important in your design or not?
In other word, are you going to use your classes AND their bases each other interchangeably, with functions just taking a std::map* or std::map& parameter, pretending those function to call std::map functions resulting in calls to your methods?
If yes, inheritance is NOT THE WAY TO GO. There are no virtual methods in std::map, hence runtime polymorphism will not work.
If no, that is: you're just writing your own class reusing both std::map behavior and interface, with no intention of interchange their usage (in particular, you are not allocating your own classes with new and deletinf them with delete applyed to an std::map pointer), providing just a set of functions taking yourclass& or yourclass* as parameters, that that's perfectly fine. It may even be better than a typedef, since your function cannot be used with a std::map anymore, thus separating the functionalities.
The alternative can be "encapsulation": that is: make the map and explicit member of your class letting the map accessible as a public member, or making it a private member with an accessor function, or rewriting yourself the map interface in your class. You gat finally an unrelated type with tha same interface an its own behavior. At the cost to rewrite the entire interface of something that may have hundredths of methods.
NOTE:
To anyone thinking about the danger of the missing of vitual dtor, note tat encapluating with public visibility won't solve the problem:
class myclass: public std::map<something...>
{};
std::map<something...>* p = new myclass;
delete p;
is UB excatly like
class myclass
{
public:
std::map<something...> mp;
};
std::map<something...>* p = &((new myclass)->mp);
delete p;
The second sample has the same mistake as the first, it is just less common: they both pretend to use a pointer to a partial object to operate on the entire one, with nothing in the partial object letting you able to know what the "containing one" is.

Why can't we create an instance of an abstract class?

I found in many places that :
An Abstract Class is a class which is supposed to be used as a base class.
An Abstract Class is a class which has atleast one Pure Virtual Function.
But one thing that always strikes my mind is why can't we create an instance of an abstract class? Many places on the Internet say there is no point in creating an instance, or some say that they are supposed to be used as base classes. But why is it an error to create an instance of an abstract class?
Your void bar()=0; is not valid -- the =0 notation can only be used with virtual functions.
The whole point of an abstract class is that it's abstract -- you've defined an interface but not an implementation. Without an implementation, instantiating the class wouldn't produce a meaningful or useful result. If it does/would make sense to instantiate objects of that class, then you simply don't want to use an abstract class in the first place.
For example, consider device drivers. We might have a driver for an abstract storage device. We define some capabilities for that device, such as reading and writing data. That abstract class gives any code that wants to read/write data the ability to work with an concrete class that derives from that abstract class.
We can't just instantiate our abstract storage device though. Instead, we need a concrete object like a thumb drive, disk drive, etc., to actually read from/write to. The concrete class is needed because we need code specific to the actual device to carry out the commands we've defined in our abstract base. Our abstract storage class just has a read or write, but do the reading or writing, we need a driver for a specific device. One might know how to talk to a SATA hard drive, while another knows how to talk to a USB thumb drive and a third knows how to read from or write to an SD card. We can't, however, just say "I'm going to create an abstract storage device", and talk to it without defining the actual code that will translate a "write" command into (for example) the right signals going over SATA, USB, Firewire, etc., to get the data onto a real drive.
As such, attempting to instantiate our abstract class makes no sense, and isn't allowed. We just use the abstract base class so the rest of the system can deal with all devices uniformly. The rest of the code doesn't care how the signals are different from each other -- it just sees a bunch of disk drives, and can work with all of them, even though the details of reading data over USB are completely different from reading over Firewire (for example).
An abstract class represents something that isn't specific enough to be instantiated. For instance, what if someone asked you to create a vehicle? You'd have to ask, "what kind of vehicle?" You wouldn't know whether to create a car, a sled, or a space shuttle. There's no such object as a "vehicle". Yet "vehicle" is a useful abstraction that can be used to group objects, indicating common behaviors among them. That's what abstract classes are for.
An abstract class is more than an interface. It may have data members. It may have member functions that are not pure virtual, or non-virtual at all. Even a pure virtual function may have a body, providing a default implementation. So this is not about a physical impossibility of instantiating an abstract class.
The main point is that a pure virtual function is a virtual function that must be overridden by a derived class. That means that a derived class must be defined, and the way to force that is to forbid the instantiation of an abstract class.
An abstract class is not specific enough to be instantiated. Not necessarily because it is missing a definition of a function, because it may not be missing it. It is not specific enough because it represents an abstract concept, which must be made more specific before it can be instantiated.
That's the whole point of an abstract class: that some details must be provided by the implementor.
Think about it: what would be the point of marking a class as abstract if you could instantiate it directly? Then it would be no different than any other class.
The reason an abstract class cannot be instantiated is: what do you do if you execute the pure virtual function? That would be a serious error, and it's better to catch that at compile-time than at runtime.
In abstract class no method definition is given, only structure is provided. If we could instantiate abstract class and call those method, it will be a huge mess. Abstract class is use to maintain a design pattern of the code.
Only Chuck Norris can instantiate an abstract class.
https://api.chucknorris.io/jokes/ye0_hnd3rgq68e_pfvsqqg

what's interface vs. methods, abstraction vs. encapsulation in C++

I am confused about such concepts when I discussed with my friend.
My friend's opinions are
1) abstraction is about pure virtual function.
2) interface is not member functions, but interface is pure virtual functions.
I found that in C++ primer, interface are those operations the data type support, so member functions are interface.
My opinions are
1) abstraction is about speration of interface and implementation;
2) member functions are interfaces.
So could anybody clarify these concepts for me?
1) the difference among abstraction, abstract data type and abstract class.
2) the difference between interface and member functions.
3) the difference between abstraction and encapsulation.
I think your main problem is that you and your friend are using two different definitions of the word "interface", so you're both right in different ways.
You are using "interface" in the everyday sense of "a defined way to inter-operate with something", as in "the interface between my computer and my keyboard is USB" or "the interface between the vacuum and the wall power is an outlet." In that sense, yes, methods (even concrete ones) are interfaces, since they define a way to inter-operate with an object. That's not to say that this is not applicable to software -- it is the sense of "interface" used in the term Application Programming Interface (API).
Your friend is using "interface" in the more specific object oriented programming jargon sense of "a separately defined set of operations that a class can choose to guarantee that it will support". Here, the defining characteristic of an "interface" is that it has no implementation of its own. A class is supposed to support an interface by providing an implementation of the methods defined by the interface. Since C++ has no explicit concept of an interface in this sense, the equivalent construct is a class with only pure virtual functions (aka an Abstract Data Type).
"Abstraction", on the other hand, is about many things and again you are both right. Abstraction in a general sense means being able to focus on higher-level concepts rather than lower level details. Encapsulation is a type of abstraction because its purpose is to hide the implementation details of the methods of a class; the implementation can change without the class definition changing. Pure virtual functions ("interfaces" in the OO-jargon sense) are another type of abstraction because they can, if used properly, hide not only the implementation but also the true underlying object type; the type being used can change so long as both types implement the same interface.
The same terms can be used for different things, which is what is happening here.
"Abstract" in C++ means a method that doesn't have an implementation at all (you can't instantiate an object with Abstract members.)
"Abstraction" is simply the concept of "modeling". Modelling is making something complex look simpler by ignoring some details. In programming, you want to break operations and concepts up into components, and for each component, abstract away details about external components that don't affect the current component's operation.
A programming "Interface" is a way of implementing "Abstraction". Rather than have all the source code and internal operations of a component, you only see the operations that are relevent to how you're using the object. An "Interface" in C++ is implemented by marking all methods on a class as "abstract" (also called "pure virtual".) That's done by putting an '= 0' after the method declaration but before the semicolon. The method has to be marked 'virtual' for this to be legal.
In other words, an abstract C++ class is one that has at least one pure virtual method, and an interface is implemented in C++ by making all member functions pure virtual.
Encapsulation is a fuzzy term, but to me it means a technique of implementing abstraction. It means "information hiding". You're hiding the internal details of how an object performs its "contract". The Contract is expressed through interfaces, which to my mind is a more powerful form of abstraction. Any C++ class with protected or private members uses encapsulation, but a class implementing only pure virtual methods is describing a contract, promising to deliver certain services for which you need to know absolutely nothing about how they are implemented or about other services the same object may implement.
The same object may fill several contracts, and by exposing multiple, disjoint interfaces, it doesn't force clients to know about all of the auxilliary functions of the object. For example, an object may be able to tell you a bank account balance, and it also may be able to be serialized/deserialized to a database. You could just have one class with all of those operations exposed as member functions. I prefer to define two interfaces, 'IDatabaseSerializable' and 'IBankAccount', and put the appropriate operations in the appropriate interfaces and derive from both interfaces in my implementation class. Then clients that only care about bank balances see as little extra information as possible, and the database only sees the operations that it cares about.
Virtual member functions (not neccessarily pure) in combination with inheritance are one way to express the concept of interfaces in C++, i.e. interfaces and methods are orthogonal concepts.
Another approach to interfaces in C++ is with generic code (i.e. templates), where you often don't expect any concrete type - instead you expect the type to have certain member functions with a certain semantic - if it doesn't you will get a compile error.
Some people call this concepts and you talk of a type modelling a certain concept. Concepts are not formally supported in C++ though, but libraries like Boost.ConceptCheck do a pretty good job of providing a substitute.
Abstraction means that someone can use your code without knowing about implementation details. The thing that makes this complicated is that things that are implementation details in one context may not be in others. An abstract data type is a data type that cannot be instantiated and only describes attributes of its subtypes. An abstract class is just something that's an abstract data type and a class.
An interface can be implicitly defined by a set of member functions (though to be a useful abstraction these should at least be virtual so that there is more than one possible implementation of the interface). It can also be defined explicitly as a class with only pure virtual functions (in C++) or an interface (in Java, C# and D).
Abstraction is when you don't have to know about the implementation details of something. Encapsulation is when you can't know about them. For example, a class that is otherwise well-designed from an OO perspective, but doesn't bother setting its member variables to private can still be a useful abstraction, but it is not encapsulated.

How do Concepts differ from Interfaces?

How do Concepts (ie those recently dropped from the C++0x standard) differ from Interfaces in languages such as Java?
Concepts are for compile-time polymorphism, That means parametric generic code. Interfaces are for run-time polymorphism.
You have to implement an interface as you implement a Concept. The difference is that you don't have to explicitly say that you are implementing a Concept. If the required interface is matched then no problems. In the case of interfaces, even if you implemented all the required functions, you have to excitability say that you are implementing it!
I will try to clarify my answer :)
Imagine that you are designing a container that accepts any type that has the size member function. We formalize the Concept and call it HasSize, of course we should define it elsewhere but this is an example no more.
template <class HasSize>
class Container
{
HasSize[10]; // just an example don't take it seriously :)
// elements MUST have size member function!
};
Then, Imagine we are creating an instance of our Container and we call it myShapes, Shape is a base class and it defines the size member function. Square and Circle are just children of it. If Shape didn't define size then an error should be produced.
Container<Shape> myShapes;
if(/* some condition*/)
myShapes.add(Square());
else
myShapes.add(Circle());
I hope you see that Shape can be checked against HasSize at compile time, there is no reason to do the checking at run-time. Unlike the elements of myShapes, we could define a function that manipulates them :
void doSomething(Shape* shape)
{
if(/* shape is a Circle*/)
// cast then do something with the circle.
else if( /* shape is a Square */)
// cast then do something with the square.
}
In this function, you can't know what will be passed till run-time a Circle or a Square!
They are two tools for a similar job, though Interface-or whatever you call them- can do almost the same job of Concepts at run-time but you lose all benefits of compile-time checking and optimization!
Concepts are likes types (classes) for templates: it's for the generic programming side of the language only.
In that way, it's not meant to replace the interface classes (assuming you mean abstract classes or other C++ equivalent implementation of C# or Java Interfaces) as it's only meant to check types used in template parameters to match specific requirements.
The type check is only done at compile time like all the template code generation and whereas interface classes have an impact on runtime execution.
Concepts are implicit interfaces. In C# or Java a class must explicitly implement an interface, whereas in C++ a class is part of a concept merely as long as it meets the concept's constraints.
The reason you will see concepts in C++ and not in Java or C# is because C++ doesn't really have "interfaces". Instead, you can simulate an interface by using multiple inheritance and abstract, memberless base classes. These are somewhat of a hack and can be a headache to work with (e.g. virtual inheritance and The Diamond Problem). Interfaces play a critical role in OOP and polymorphism, and that role has not been adequately fulfilled in C++ so far. Concepts are the answer to this problem.
It's more or less a difference in the point of view. While an interface (as in C#) is specified similar to a base class, a concept can also be matched automatically (similar to duck-typing in Python). It is still unclear to which level C++ is going to support automatic concept matching, which is one of the reasons why they dropped it.
To keep it simple, as per my understanding.
Concept is a constraint on the template parameter of a Type (i.e., class or struct) or a Method
Interfaces is a contract that Type (i.e., class Or struct) has to implement.

Practical Uses for the "Curiously Recurring Template Pattern"

What are some practical uses for the "Curiously Recurring Template Pattern"? The "counted class" example commonly shown just isn't a convincing example to me.
Simulated dynamic binding.
Avoiding the cost of virtual function calls while retaining some of the hierarchical benefits is an enormous win for the subsystems where it can be done in the project I am currently working on.
It's also especially useful for mixins (by which I mean classes you inherit from to provide functionality) which themselves need to know what type they are operating on (and hence need to be templates).
In Effective C++, Scott Meyers provides as an example a class template NewHandlerSupport<T>. This contains a static method to override the new handler for a particular class (in the same way that std::set_new_handler does for the default operator new), and an operator new which uses the handler. In order to provide a per-type handler, the parent class needs to know what type it is acting on, so it needs to be a class template. The template parameter is the child class.
You couldn't really do this without CRTP, since you need the NewHandlerSupport template to be instantiated separately, with a separate static data member to store the current new_handler, per class that uses it.
Obviously the whole example is extremely non-thread-safe, but it illustrates the point.
Meyers suggests that CRTP might be thought of as "Do It For Me". I'd say this is generally the case for any mixin, and CRTP applies in the case where you need a mixin template rather than just a mixin class.
The CRTP gets a lot less curious if you consider that the subclass type that is passed to the superclass is only needed at time of method expansion.
So then all types are defined.
You just need the pattern to import the symbolic subclass type into the superclass, but it is just a forward declaration - as all formal template param types are by definition - as far as the superclass is concerned.
We use in a somewhat modified form, passing the subclass in a traits type structure to the superclass to make it possible for the superclass to return objects of the derived type. The application is a library for geometric calculus ( points, vectors, lines, boxes ) where all the generic functionality is implemented in the superclass, and the subclass just defines a specific type : CFltPoint inherits from TGenPoint. Also CFltPoint existed before TGenPoint, so subclassing was a natural way of refactoring this.
Generally it is used for polymorphic-like patterns where you do not need to be able to choose the derived class at runtime, only at compile time. This can save the overhead of the virtual function call at runtime.
For a real-world library use of CRTP, look at ATL and WTL (wtl.sf.net). It is used extensively there for compile-time polymorphism.