I am currently working through the Educative course Grokking the Coding Interview. While it is a very good course and does explain the algorithms very well, it does not always explain the code.
A few times I have seen the use of virtual functions, as a dynamic function (to be clear, I mean functions that require the instantiation of an object in order to be called). From reading up on virtual functions, I gather that they are used to achieve some OOP principles such as run time polymorphism, or just generally improving the maintainability of some code. In the case of these algorithms questions, that seems to be completely unnecessary. In fact, I am able to just delete the virtual keyword and the code runs all the same.
My question is: Why might the author be using virtual to define these functions?
Here is an example of the course's author's use of virtual functions:
using namespace std;
#include <iostream>
#include <queue>
#include <vector>
class MedianOfAStream {
public:
priority_queue<int> maxHeap; // containing first half of numbers
priority_queue<int, vector<int>, greater<int>> minHeap; // containing second half of numbers
virtual void insertNum(int num) {
if (maxHeap.empty() || maxHeap.top() >= num) {
maxHeap.push(num);
} else {
minHeap.push(num);
}
// either both the heaps will have equal number of elements or max-heap will have one
// more element than the min-heap
if (maxHeap.size() > minHeap.size() + 1) {
minHeap.push(maxHeap.top());
maxHeap.pop();
} else if (maxHeap.size() < minHeap.size()) {
maxHeap.push(minHeap.top());
minHeap.pop();
}
}
virtual double findMedian() {
if (maxHeap.size() == minHeap.size()) {
// we have even number of elements, take the average of middle two elements
return maxHeap.top() / 2.0 + minHeap.top() / 2.0;
}
// because max-heap will have one more element than the min-heap
return maxHeap.top();
}
};
int main(int argc, char *argv[]) {
MedianOfAStream medianOfAStream;
medianOfAStream.insertNum(3);
medianOfAStream.insertNum(1);
cout << "The median is: " << medianOfAStream.findMedian() << endl;
medianOfAStream.insertNum(5);
cout << "The median is: " << medianOfAStream.findMedian() << endl;
medianOfAStream.insertNum(4);
cout << "The median is: " << medianOfAStream.findMedian() << endl;
}
Again, from everything I've read, I really just don't see the point. And, running this exact code without the virtual keyword works just fine. My thinking would be that this is some sort of best practice in C++ land.
Thanks for any explanation!
From reading up on virtual functions, I gather that they are used to achieve some OOP principles such as run time polymorphism
Yes.
or just generally improving the maintainability of some code
No.
In the case of these algorithms questions, that seems to be completely unnecessary. In fact, I am able to just delete the virtual keyword and the code runs all the same.
Yes.
My question is: Why might the author be using virtual to define these functions?
I see three possibilities here:
The author will inherit this class in a later chapter, and has "got ready" by putting virtual on the member function declarations now. I think that's a bit of an odd choice, personally (particularly as they would also likely want to add a virtual destructor at that time), but maybe keep reading and find out!
The author does it, always, out of habit, even when they don't need to. Some people like to make every function virtual so that you get dynamic polymorphism "by default", without having to change your base class when you later derive from it. I think that's also a very strange thing to do, personally.
The author made a mistake.
a dynamic function (to be clear, I mean functions that require the instantiation of an object in order to be called)
We call those non-static member functions.
Related
As far as I know each created object has its own address, and each object's method also has its own address. I want to verify that with the following idea:
Step 1: Build class A with public method, its name is "method".
Step 2: Create two objects in class A, they are object "b" and object "c".
Step 3: Access the addresses of "b.method" and "c.method" to check that they are equal by using a function pointer.
But I met the problem in step 3 and have found every way to solve but failed.
So I posted up here to ask people to help me how to verify what I said above. Thanks everyone!
And here is my C++ code:
#include<iostream>
using namespace std;
class A
{
public:
int a;
void method()
{
//do something
}
static void (*fptr)();
};
int main()
{
A b, c;
A::fptr= &(b.method); //error: cannot convert 'A::method' from type
// 'void(A::)()' to type 'void (*)()'
cout << A::fptr << endl;
A::fptr= &(c.method); //error: cannot convert 'A::method' from type
//'void(A::)()' to type 'void (*)()'
cout << A::fptr << endl;
return 0;
}
Member functions are not like typical functions. The main difference is the way they are called (they have an implicit this argument), but that difference is enough for the language to demand a new way of defining pointers to them. See here for more details.
The following code prints the address in memory of a method:
#include <iostream>
class A {
public:
void method() {
}
};
int main() {
auto ptr = &A::method;
std::cout << reinterpret_cast<void*>(ptr) << "\n";
return 0;
}
As you can see, I had to cast the pointer to a void* to fool the compiler. G++ prints out a warning on that line, but otherwise does what you want with it.
Notice that the type of ptr is void (A::*)(), i.e. "a pointer to a method in A that receives no arguments and returns void". A pointer to methods in your B and C may be slightly different. They should convert to pointers to A, so you might want to go through that when comparing (or just cast to void* and ignore the warning).
Edited to add:
It seems no cast is needed for comparison. You can just directly compare the two pointers to methods, and they will return true or false correctly.
Thank you everyone!
I've been wondering about this for a long time, and now I've figured out the answer myself, there's only one "method()" that's created on memory, even if there are hundreds of objects created. All objects created that want to use this method will have to find the address of this method. Here is the code to prove what I said:
#include<iostream>
using namespace std;
class A
{
public:
int a;
void method()
{
//do something
}
static void (*fptr)();
};
int main()
{
A b,c;
if(&(b.method)==&(c.method))
{
cout<<"they are same\n";
}
else
{
cout<<"they are not same\n";
}
return 0;
}
The compiler and linker does not have to give distinct functions, distinct implementations.
On at least some platforms, the compiler will spot that 2 functions have the same implementation, and merge the 2 functions into a single piece of code. That limits the amount of bloat added by the template system, but stops it being a guaranteed behavior to identify different member functions.
The compiler can
inline all the examples of a single piece of code, and the result is it doesn't have an address.
share implementations where the code is the same.
create multiple implementations of the same function if it thinks it can be done faster.
When C++ was invented, there was a lot of effort to ensure that a C++ compilation unit was able to call a C compilation unit, and the result of this effort, was that many items of the C++ implementation became visible using compatibility tricks.
The C++ pointer to member function had no backwards-compatibility baggage, and thus no reason to allow it to be inspected. As such it is an opaque item, which can be implemented in multiple ways.
In your example there is only one copy of the method in memory. But i cannot think of any easy way to verify that. You can make thousands of objects and see the memory consumption. You can explore the memory occupied by your object in debugger. The memory consumption may be affected by operating system strategy for assigning memory to process. You can also explore disassembly at https://gcc.godbolt.org/
Relevant start for you would be https://godbolt.org/g/emRYQy
I have this variable; Furniture **furnitures;
Which is an abstract baseclass to 2 subclasses, Bookcase and Couch. I add these randomly;
furnitures[n++] = new Bookcase ();
furnitures[n++] = new Couch();
.
.
For the sake of explaination. Lets set some minor variables.
Furniture private: name, prize
Bookcase private: size
Couch private: seats
How would I go about if I wanted to print out information such as; name and seats?
There are various of problems in this issue. 1, distinguish which subclass is which when I use Furniture[i]. 2, I dont want to blend too much unneccessary functions between the two subclasses that arent needed.
class Furniture
{
virtual void output() = 0;
};
class Couch : public Furniture
{
void output() override;
};
class Bookshelf : public Furniture
{
void output() override;
};
You could define the function in Furniture to save from duplicate code in subclasses like this:
void Furniture::output()
{
// We assume here the output is to cout, but you could also pass the necessary
// stream in as argument to output() for example.
cout << name << price;
}
void Couch::output()
{
Furniture::output();
cout << seats;
}
void Bookshelf::output()
{
Furniture::output();
cout << size;
}
You should never use arrays polymorhphically. Read the first item (I think it's the first) in Scott Meyers' More Effective C++ book to find out why!
In fact, you should almost never use raw arrays in C++ anyway. A correct solution is to use a std::vector<Furniture*>.
How would I go about if I wanted to print out information such as;
name and seats?
There are various of problems in this issue. 1, distinguish which
subclass is which when I use Furniture[i]. 2, I dont want to blend too
much unneccessary functions between the two subclasses that arent
needed..
You are facing this problem because you are abusing object-oriented programming. It's simple: object-oriented programming makes sense when different types implement an abstract common operation and the concrete type is chosen at run-time. In your case, there is no common operation. Printing (or receiving) the number seats is for one type, printing (or receiving) a size is for the other type.
That's not to say that it's bad or wrong, but it's simply not object-oriented.
Now C++ would not be C++ if it didn't offer you a dangerous tool to get out of every dead end you've coded yourself into. In this case, you can use Run-Time Type Identifcation (RTTI) to find out the concrete type of an object. Google for typeid and dynamic_cast and you'll quickly find the solution. But remember, using RTTI for this problem is a workaround. Review your class design, and change it if necessary.
I'm working on a code which needs to be extremely flexible in nature, i.e. especially very easy to extend later also by other people. But I'm facing a problem now about which I do not even know in principal how to properly deal with:
I'm having a rather complex Algorithm, which at some point is supposed to converge. But due to its complexity there are several different criteria to check for convergence, and depending on the circumstances (or input) I would want to have different convergence criteria activated. Also it should easily be possible to create new convergence criteria without having to touch the algorithm itself. So ideally I would like to have an abstract ConvergenceChecker class from which I can inherit and let the algorithm have a vector of those, e.g. like this:
//Algorithm.h (with include guards of course)
class Algorithm {
//...
vector<ConvergenceChecker*> _convChecker;
}
//Algorithm.cpp
void runAlgorithm() {
bool converged=false;
while(true){
//Algorithm performs a cycle
for (unsigned i=0; i<_convChecker.size(); i++) {
// Check for convergence with each criterion
converged=_convChecker[i]->isConverged();
// If this criterion is not satisfied, forget about the following ones
if (!converged) { break; }
}
// If all are converged, break out of the while loop
if (converged) { break; }
}
}
The problem with this is that each ConvergenceChecker needs to know something about the currently running Algorithm, but each one might need to know totally different things from the algorithm. Say the Algorithm changes _foo _bar and _fooBar during each cycle, but one possible ConvergenceChecker only needs to know _foo, another one _foo and _bar, and it might be that some day a ConvergenceChecker needing _fooBar will be implemented. Here are some ways I already tried to solve this:
Give the function isConverged() a large argument list (containing _foo, _bar, and _fooBar). Disadvantages: Most of the variables used as arguments will not be used in most cases, and if the Algorithm would be extended by another variable (or a similar algorithm inherits from it and adds some variables) quite some code would have to be modified. -> possible, but ugly
Give the function isConverged() the Algorithm itself (or a pointer to it) as an argument. Problem: Circular dependency.
Declare isConverged() as a friend function. Problem (among others): Cannot be defined as a member function of different ConvergenceCheckers.
Use an array of function pointers. Does not solve the problem at all, and also: where to define them?
(Just came up with this while writing this question) Use a different class which holds the data, say AlgorithmData having Algorithm as a friend class, then provide the AlgorithmData as a function argument. So, like 2. but maybe getting around circular dependency problems. (Did not test this yet.)
I'd be happy to hear your solutions about this (and problems you see with 5.).
Further notes:
Question title: I'm aware that 'strongly dependent classes' already says that most probably one is doing something very wrong with designing the code, still I guess a lot of people might end up with having that problem and would like to hear possibilities to avoid it, so I'd rather keep that ugly expression.
Too easy?: Actually the problem I presented here was not complete. There will be a lot of different Algorithms in the code inheriting from each other, and the ConvergenceCheckers should of course ideally work in appropriate cases without any further modification even if new Algorithms come up. Feel free to comment on this as well.
Question style: I hope the question is neither too abstract nor too special, and I hope it did not get too long and is understandable. So please also don't hesitate to comment on the way I ask this question so that I can improve on that.
Actually, your solution 5 sounds good.
When in danger of introducing circular dependencies, the best remedy usually is to extract the part that both need, and moving it to a separate entity; exactly as extracting the data used by the algorithm into a separate class/struct would do in your case!
Another solution would be passing your checker an object that provides the current algorithm state in response to parameter names expressed as string names. This makes it possible to separately compile your conversion strategies, because the interface of this "callback" interface stays the same even if you add more parameters to your algorithm:
struct AbstractAlgorithmState {
virtual double getDoubleByName(const string& name) = 0;
virtual int getIntByName(const string& name) = 0;
};
struct ConvergenceChecker {
virtual bool converged(const AbstractAlgorithmState& state) = 0;
};
That is all the implementers of the convergence checker need to see: they implement the checker, and get the state.
You can now build a class that is tightly coupled with your algorithm implementation to implement AbstractAlgorithmState and get the parameter based on its name. This tightly coupled class is private to your implementation, though: the callers see only its interface, which never changes:
class PrivateAlgorithmState : public AbstractAlgorithmState {
private:
const Algorithm &algorithm;
public:
PrivateAlgorithmState(const Algorithm &alg) : algorithm(alg) {}
...
// Implement getters here
}
void runAlgorithm() {
PrivateAlgorithmState state(*this);
...
converged=_convChecker[i]->converged(state);
}
Using a separate data/state structure seems easy enough - just pass it to the checker as a const reference for read-only access.
class Algorithm {
public:
struct State {
double foo_;
double bar_;
double foobar_;
};
struct ConvergenceChecker {
virtual ~ConvergenceChecker();
virtual bool isConverged(State const &) = 0;
}
void addChecker(std::unique_ptr<ConvergenceChecker>);
private:
std::vector<std::unique_ptr<ConvergenceChecker>> checkers_;
State state_;
bool isConverged() {
const State& csr = state_;
return std::all_of(checkers_.begin(),
checkers_.end(),
[csr](std::unique_ptr<ConvergenceChecker> &cc) {
return cc->isConverged(csr);
});
}
};
Maybe the decorator pattern can help in simplifying an (unknown) set of convergence checks. This way you can keep the algorithm itself agnostic to what convergence checks may occur and you don't require a container for all the checks.
You would get something along these lines:
class ConvergenceCheck {
private:
ConvergenceCheck *check;
protected:
ConvergenceCheck(ConvergenceCheck *check):check(check){}
public:
bool converged() const{
if(check && check->converged()) return true;
return thisCheck();
}
virtual bool thisCheck() const=0;
virtual ~ConvergenceCheck(){ delete check; }
};
struct Check1 : ConvergenceCheck {
public:
Check1(ConvergenceCheck* check):ConvergenceCheck(check) {}
bool thisCheck() const{ /* whatever logic you like */ }
};
You can then make arbitrary complex combinations of convergence checks while only keeping one ConvergenceCheck* member in Algorithm. For example, if you want to check two criteria (implemented in Check1 and Check2):
ConvergenceCheck *complex=new Check2(new Check1(nullptr));
The code is not complete, but you get the idea. Additionally, if you are a performance fanatic and are afraid of the virtual function call (thisCheck), you can apply the curiously returning template pattern to eliminate that.
Here is a complete example of decorators to check constraints on an int, to give an idea of how it works:
#include <iostream>
class Check {
private:
Check *check_;
protected:
Check(Check *check):check_(check){}
public:
bool check(int test) const{
if(check_ && !check_->check(test)) return false;
return thisCheck(test);
}
virtual bool thisCheck(int test) const=0;
virtual ~Check(){ delete check_; }
};
class LessThan5 : public Check {
public:
LessThan5():Check(NULL){};
LessThan5(Check* check):Check(check) {};
bool thisCheck(int test) const{ return test < 5; }
};
class MoreThan3 : public Check{
public:
MoreThan3():Check(NULL){}
MoreThan3(Check* check):Check(check) {}
bool thisCheck(int test) const{ return test > 3; }
};
int main(){
Check *morethan3 = new MoreThan3();
Check *lessthan5 = new LessThan5();
Check *both = new LessThan5(new MoreThan3());
std::cout << morethan3->check(3) << " " << morethan3->check(4) << " " << morethan3->check(5) << std::endl;
std::cout << lessthan5->check(3) << " " << lessthan5->check(4) << " " << lessthan5->check(5) << std::endl;
std::cout << both->check(3) << " " << both->check(4) << " " << both->check(5);
}
Output:
0 1 1
1 1 0
0 1 0
often I encounter code like
/*initializer list of some class*/:m_member(some_param,/* --> */ *this)
Reason why this is done is so that m_member can call member functions from the class that contains it...
aka
//code in class that is m_member instance of
m_parent->some_function();
I personally dislike it because I consider it pathetic design("dear child do you know what are you doing to your class encapsulation"), but I would like to know is in general this behavior bad, and if so how to avoid this kind of design.
EDIT: please dont focus on this in initalizer list, lets say it is in ctor body.
It can be disastrous, since your parent is not constructed a the time of the reference-set. The following example will demonstrate this:
#include <iostream>
using namespace std;
struct TheParent;
struct TheChild
{
TheChild(TheParent& parent);
TheParent& myParent;
};
struct TheParent
{
TheParent()
: mychild(*this)
, value(1)
{
cout << "TheParent::TheParent() : " << value << endl;
}
TheChild mychild;
int value;
};
TheChild::TheChild(TheParent& parent)
: myParent(parent)
{
cout << "TheChild::TheChild() : " << myParent.value << endl;
};
int main()
{
TheParent parent;
return 0;
}
Produces the following output, clearly noting the indeterminate state of the parent object:
TheChild::TheChild() : 1606422622
TheParent::TheParent() : 1
Bottom line: don't do it this way. You would be better served to use a dynamic child allocation instead, but even this has caveats:
#include <iostream>
using namespace std;
struct TheParent;
struct TheChild
{
TheChild(TheParent& parent);
TheParent& myParent;
};
struct TheParent
{
TheParent()
: mychild(NULL)
, value(1)
{
mychild = new TheChild(*this);
cout << "TheParent::TheParent() : " << value << endl;
}
~TheParent()
{
delete mychild;
}
TheChild* mychild;
int value;
};
TheChild::TheChild(TheParent& parent)
: myParent(parent)
{
cout << "TheChild::TheChild() : " << myParent.value << endl;
};
int main()
{
TheParent parent;
return 0;
}
This give you what you're likely hoping for:
TheChild::TheChild() : 1
TheParent::TheParent() : 1
Note, however, even this has issues if TheParent is an intermediate class in an inheritance chain, and you're desiring to access potentially overridden virtual implementations of functions in derived classes that have yet to be constructed.
Again, bottom line, if you find yourself doing this, you may want to think about why you need to in the first place.
It is bad because it is unclear how complete the parent class is at the time m_member is constructed.
For example:
class Parent
{
Parent()
: m_member(this), m_other(foo)
{ }
};
class Member
{
Member(Parent* parent)
{
std::cout << parent->m_other << std::endl; // What should this print?
}
};
A slightly better approach if a parent pointer is needed is for Member to have a 'setParent' method called in the body of the constructor.
Like the vast majority of programming practices, it is impossible to say that it is bad in general (and if you do, you are a bad person and should be ashamed). I use this sometimes, but it is uncommon; however, it is not a thing I would try to purposefully avoid by changing my class design.
Note how I used "I" a lot in the above paragraph, a sure sign this is a highly subjective issue.
I see the language as a tool to implement the solution for a given problem. By design, C++ allows explicit uses of this and other OO languages don't. Thus, I look at language features as tools in my toolbox, and every so often there is a use to bring out one tool or another.
However, and that's where coding style and practice comes in, I should know what I'm doing. I should know how to use my tools, and I should know the implications of their use. There is a defined order in which C++ initializes a new object, and as long as I work with this then I'm good. Unfortunately, some times people get lucky; other times they create bugs that way. You need to know your tools and how to use them :-)
To answer your question with my personal opinion: I try to avoid this particular construct, but on occasion I had to use it. Even pondering a class re-design wouldn't have avoided that. And so I filed this occasion under, "Ah well, sometimes my design just can't be modeled in clean-clean straight OO, the dependencies between the classes are too tight and performance matters too much."
I'm currently reading a c++ book, and I have a few questions.
1) Is void only used to declare a return type in this example?
2) If void causes it NOT to return data to the calling function, why is it still displaying the message "Welcome to the Grade Book!"?
3) Isn't it easier to create a simple function instead of making an object?
#include <iostream>
using namespace std;
class GradeBook
{
public:
void displayMessage()
{
cout << "Welcome to the Grade Book!" << endl;
}
};
int main()
{
GradeBook myGradeBook;
myGradeBook.displayMessage();
}
That's the only use in this example. You can also have pointers to void (void *).
You're not returning that message. You're printing it. In C++, methods and functions can have side effects. One possible side effect is output.
Yes, in this case. However, this is not a realistic example of the benefits of objects. For that, see How do I describe Object-Oriented Programing to a beginner? Is there a good real-world analogy? among many places.
Is void only used to declare a return type in this example?
Yes, it indicates that displayMessage() will not return back anything to it's caller.
It can also be used as a void *, i.e: A generic pointer which can point to anything, but it is not being used in that way in your example.
If void causes it NOT to return data to the calling function, why is it still displaying the message "Welcome to the Grade Book!"?
The message is not returned to the caller of the function, the message is directed to the standard output when the control was in the function and executing that particular statement.
Isn't it easier to create a simple function instead of making an object?
It's not a matter of ease. It is more of an matter of Object Oriented design principles.
The purpose of having classes and member functions is to bind together the data and the methods that operate on that data in a single unit. You might want to pick up a good book and read up Encapsulation & Abstraction.
The Definitive C++ Book Guide and List
In your case the function "displayMeassage" is not returning the string, it is just printing your message.
Returning means, suppose an example:
class A
{
int num=0;
int getNum()
{
return num;
}
};
void main()
{
A a;
int no=a.getNum();
cout<<"no : "<<no;
}
In above example, then way getNum is returning the number that is what returning is
called.
Whatever you are taking the example is not good to understand the return concept.
Thanks